我已經開始學習Haskell,我想我要實作序數,使用常見的("von Neumann")定義。所以我寫道:
ordinal 0 = []
ordinal x = [ ordinal n | n<-[1...(x-1)] ]
但是,解釋器并不滿意,它反而告訴我,據說
* 無法匹配 type `a' with `[a]'
Expected: t -> a
Actual: t -> [a] 。
* Relevant 系結包括
ordinal :: t -> a (bound at fist.hs:7: 1)
|
1 |序號 0 = []
| ^^^^^^^^^^^^^^^...
現在我想這里可能出錯的是,這個串列不是同質型別的。但是我如何切換到圖元呢?是否有 "元組理解 "這樣的東西呢?
uj5u.com熱心網友回復:
這個函式的結果是一個單一的空值,或一個這樣的串列,或一個串列的串列,或一個串列的串列,等等,取決于輸入的數字。沒有一個單一的串列型別可以代表所有這些值。
。...或者有嗎?這個型別不是一個串列(即[]),它只代表一個單一的平面數值序列,但有這樣一個型別:
data Ordinal = Zero | Ordinal [Ordinal] deriving Show
而你的函式應該被修改為將每一級的串列嵌套包裹在一個Ordinal建構式中:
ordinal 0 = Zero
序數 x = Ordinal [ 序數n | n<-[1...(x-1)] ]
例子:
*Main> ordinal 3
Ordinal [Ordinal [] 。 Ordinal [Ordinal []],Ordinal [Ordinal []] 。
uj5u.com熱心網友回復:
首先,串列不是集合。
第二,串列要求所有元素具有相同的型別,所以你不能在一個串列中擁有不同嵌套深度的串列。
但是從"一切都是一個集合 "的角度來看,諸如馮-諾依曼序數這樣的構造是基于這個角度的,你可以直接在集合的基礎上定義一個 "通用型別":
import qualified Data.Set asSet
newtype UntypedSet = UntypedSet { getUntypedSet : 。Set.Set UntypedSet }.
deriving (Eq, Ord, Show)
ordinal :: Int -> UntypedSet
ordinal 0 = UntypedSet $ Set.empty
序數 x = UntypedSet $ Set.fromList [ 序數 n | n <- [0..x-1] ] ]
注意定義 如果你想變得古怪(不一定推薦),你實際上仍然可以使用 "串列 "符號: 那么,
標籤:[1...x-1]/code>在你的實作中實際上是錯誤的,它應該是[0...x-1]/code>。
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE TypeFamilies #-}
import qualified Data.Set as Set
import GHC.Exts (IsList(.))
newtype UntypedSet = UntypedSet { getUntypedSet : : Set.Set UntypedSet }.
deriving (Eq, Ord)
instance IsList UntypedSet where
type Item UntypedSet = UntypedSet
fromList = UntypedSet . Set.fromList
toList (UntypedSet s) = Set.toList s
。
instance Show UntypedSet where
show = show . toList
ordinal :: Int -> UntypedSet ::.
ordinal 0 = []
ordinal x = fromList [ ordinal n | n <- [0.x-1 ] ]
*Main> ordinal 4
[[],[[]],[[],[[]]],[[],[[]],[[],[[]]]]]
