我是一个对 Haskell 感兴趣的初学者,我一直在尝试自己实现 flatmap (>>=) 以更好地理解它。目前我有
flatmap :: (t -> a) -> [t] -> [a]
flatmap _ [] = []
flatmap f (x:xs) = f x : flatmap f xs
它实现了“地图”部分,但没有实现“平面”。
我所做的大部分修改都会导致令人沮丧且毫无信息的结果
Occurs check: cannot construct the infinite type: a = [a]
When generalising the type(s) for `flatmap'
error.
我缺少什么?
当您指定的类型签名与函数的实际类型不匹配时,就会发生这样的错误。由于您没有显示导致错误的代码,我不得不猜测,但我认为您将其更改为如下所示:
flatmap _ [] = []
flatmap f (x:xs) = f x ++ flatmap f xs
事实上,这是完全正确的。但是,如果您忘记更改类型签名,则会发生以下情况:
类型检查器发现您在结果上使用了 ++f x
and flatmap f xs
. Since ++
适用于相同类型的两个列表,类型检查器现在知道两个表达式必须计算为相同类型的列表。现在类型检查器也知道flatmap f xs
将返回类型的结果[a]
, so f x
还必须有类型[a]
。然而在类型签名中它说 f 具有类型t -> a
, so f x
必须有类型a
。这导致类型检查器得出结论:[a] = a
这是矛盾的,会导致您看到错误消息。
如果将类型签名更改为flatmap :: (t -> [a]) -> [t] -> [a]
(或删除它),它会起作用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)