data NestedList a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem element) = [element]
flatten (List []) = []
flatten (List (first:rest)) = flatten first ++ flatten (List (rest))
main = print $ flatten $ List []
Run Code Online (Sandbox Code Playgroud)
我在haskell中写了上面看到的代码.例如,当我使用任何其他参数执行此操作时
main = print $ flatten $ List [Elem 1, Elem 2]
main = print $ flatten $ Elem 1
Run Code Online (Sandbox Code Playgroud)
它给
[1, 2]
[1]
Run Code Online (Sandbox Code Playgroud)
分别.
当我用空List执行它时失败.
main = print $ flatten $ List []
Run Code Online (Sandbox Code Playgroud)
错误信息
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 23 others
In the expression: print
In the expression: print $ flatten $ List []
In an equation for `main': main = print $ flatten $ List []
Run Code Online (Sandbox Code Playgroud)
问题
NestedList定义以接受空List吗?如果是这样,我该怎么做.它很混乱.Don*_*art 16
列表类型是多态的.由于您不提供元素,只提供空列表构造函数[],因此无法推断出这是什么列表类型.
是吗: [] :: [Int]
或[] :: [Maybe (Either String Double)].谁说?
你是.提供类型注释来解析多态性,然后GHC可以调度到正确的show实例.
例如
main = print $ flatten $ List ([] :: [Int])
Run Code Online (Sandbox Code Playgroud)
要在这里添加答案,你可能会反对"但是我的列表包含什么类型的东西有什么关系呢?它里面没有任何东西!"
好吧,首先,很容易构建一种情况,其中不清楚列表是否为空,无论如何类型检查讨厌查看值,它只想查看类型.这使事情变得更简单,因为这意味着在处理值时,您可以确定您已经知道所有类型.
其次,它实际上确实是什么类型的列表,即使它是空的:
ghci> print ([] :: [Int])
[]
ghci> print ([] :: [Char])
""
Run Code Online (Sandbox Code Playgroud)
问题是编译器无法知道的类型flatten $ List [].尝试自己弄清楚这个类型,你会看到它[a]适合某些人a,同时print要求它的参数是一个实例Show,并且[a]是Showif a的一个实例Show.即使你的列表是空的,所以不需要任何约束a来表示[],编译器也无法知道.
因此,将显式类型注释(对于Show存在的实例的任何类型)应该起作用:
main = print $ flatten $ List ([] :: [NestedList Int])
Run Code Online (Sandbox Code Playgroud)
要么
main = print $ flatten $ List ([] :: [NestedList ()])
Run Code Online (Sandbox Code Playgroud)
要么
main = print fl
where
fl :: [()]
fl = flatten $ List []
Run Code Online (Sandbox Code Playgroud)