Haskell 没有因使用“print';类型变量'a0';含糊不清
我用haskell编写了上述代码。当我使用任何其他参数执行此操作时,例如Haskell 没有因使用“print';类型变量'a0';含糊不清,haskell,Haskell,我用haskell编写了上述代码。当我使用任何其他参数执行此操作时,例如 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)) mai
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 []
它给
main = print $ flatten $ List [Elem 1, Elem 2]
main = print $ flatten $ Elem 1
分别
当我使用空列表执行它时,它会失败
[1, 2]
[1]
错误消息
main = print $ flatten $ List []
问题
嵌套列表
定义以接受空的列表
?如果是,我该怎么做。这很令人困惑列表类型是多态的。由于您不提供元素,只提供空列表构造函数
[]
,因此无法推断这是什么列表类型
是:[]:[Int]
或者[]::[可能(两个字符串中的任意一个)]
。谁说呢
你是。提供类型注释以解决多态性,然后GHC可以分派到正确的show实例
例如
问题是编译器无法知道展平$List[]的类型。试着自己找出类型,对于某些
a
,你会看到它是[a]
,而print
要求它的参数是Show
的实例,[a]
是Show
的实例,如果a
是Show
的实例。即使您的列表是空的,所以不需要对a
进行任何约束来表示[]
,编译器也无法知道
因此,放置显式类型注释(对于存在Show
实例的任何类型)应该可以:
main = print $ flatten $ List ([] :: [Int])
或
或
[]
可以是浮点、字符串、布尔或任何类型的列表。因此,print
不知道使用show
的哪个实例
按照错误消息所说的去做,并给出一个明确的类型,如
([]:[Int])
要在这里添加答案,您可能会反对“但是我的列表包含什么类型的内容有什么关系?它没有任何内容!”
首先,在不清楚列表是否为空的情况下很容易构造,而且类型检查讨厌查看值,它只想查看类型。这使事情变得更简单,因为这意味着在处理值时,您可以确保您已经知道所有类型
第二,不管它是什么类型的列表,即使它是空的:
main = print fl
where
fl :: [()]
fl = flatten $ List []
GHC没有使用哪种类型的信息。当列表中有
elem1
时,它提供了numa
约束,然后GHC可以将类型变量默认为Integer
。如果没有元素,则不能默认类型变量a0
。例如,给它一个类型签名,main=print$flant$(List[]::NestedList())
,这样编译器就知道要使用哪种类型。在NestedList
之后和[()]
中,空参数是什么意思?@theourtheye()
是一个大小为零的元组。这有点像Haskell的void
。Haskell知道如何打印空元组?是的,因为“()”有一个“Show”实例。与类型为“[a]”的“[]”不同,“()”是类型为“()”,因此任何东西都不会影响打印,“显示”结果始终为“()”。
main = print $ flatten $ List ([] :: [NestedList Int])
main = print $ flatten $ List ([] :: [NestedList ()])
main = print fl
where
fl :: [()]
fl = flatten $ List []
ghci> print ([] :: [Int])
[]
ghci> print ([] :: [Char])
""