Haskell 为什么我会得到无限类型错误
我试图实现我自己的concat使用折叠和绊脚石在这里。为什么会出现“无法创建无限类型”错误Haskell 为什么我会得到无限类型错误,haskell,Haskell,我试图实现我自己的concat使用折叠和绊脚石在这里。为什么会出现“无法创建无限类型”错误 查看表达式x:y中x和y的类型-根据的定义,y的类型必须是x的任何类型的列表:。如果您试图遵循foldl的类型,特别是其累加器函数的类型,那么您最终将需要一个…列表列表。以下是如何欺骗GHCi向您显示临时表达式的类型。首先,你最初的定义 f xs = foldl conc [] xs where conc x y = (x : y) 提供有关“无限类型”“a=[a]”的错误。现在,将foldl中的con
查看表达式
x:y
中x和y的类型-根据的定义,y
的类型必须是x
的任何类型的列表:
。如果您试图遵循foldl
的类型,特别是其累加器函数的类型,那么您最终将需要一个…列表列表。以下是如何欺骗GHCi向您显示临时表达式的类型。首先,你最初的定义
f xs = foldl conc [] xs where conc x y = (x : y)
提供有关“无限类型”“a=[a]”的错误。现在,将foldl
中的conc
替换为其他内容:
f xs = foldl g [] xs where conc x y = (x : y) ; g = g
没有类型错误!如果仍有错误,请将某些表达式中使用的每个标识符替换为g2=g2
,g3=g3
等。此类定义等同于定义g=undefined
,其使用将导致错误,但更重要的是,对于我们来说,其类型可以根据需要自由更改
现在的技巧是将其定义为一些简单的值,比如布尔值:
f xs = foldl g [] xs where conc x y = (x : y) ; g = True
这给了我们一个关于“a->b->a”和“Bool”之间类型不匹配的错误。我们知道True
具有类型Bool
,因此我们得出结论g
必须是类型a->b->a
。我们也可以通过:t
命令直接找到这一点:
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
-------------
继续,我们现在可以将conc
与一些简单的值进行比较:
f xs = foldl g [] xs where conc x y = (x : y) ; g = g ; h = conc == True
我们再次得到“a->[a]->[a]”和“Bool”之间的类型不匹配错误True::Bool
(具有类型Bool
),因此conc::a->[a]->[a]
。最初我们在现在g
的位置使用它,因此它们的类型必须匹配:
g :: a -> b -> a
conc :: a -> [a] -> [a]
------
a ~ [a]
这是不可能的。foldl的类型是
(b->a->b)->b->[a]->b
,conc的类型(即(:)
)是c->[c]
。类型检查器确定b~c
和b~[c]
,这意味着c~[c]
,这是一种无限类型,在haskell中是不允许的。您可能想要foldl(flip(:)[]
,这只是反向的。回答得不错。比我的好多了!
g :: a -> b -> a
conc :: a -> [a] -> [a]
------
a ~ [a]