Haskell FlatMap

时间:2010-06-07 02:31:36

标签: haskell map flatten higher-order-functions

我是一名对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' 

错误。

我错过了什么?

1 个答案:

答案 0 :(得分:21)

当您指定的类型签名与函数的实际类型不匹配时,会发生类似这样的错误。既然你没有显示导致错误的代码,我必须猜测,但我认为你把它改成了这样的东西:

flatmap _ [] = []  
flatmap f (x:xs) = f x ++ flatmap f xs

实际情况是完全正确的。但是,如果您忘记也更改类型签名,则会发生以下情况:

类型检查器看到您对f xflatmap f xs的结果使用++。由于++适用于两个相同类型的列表,因此类型检查器现在知道两个表达式都必须计算到相同类型的列表。现在,类型检查器也知道flatmap f xs将返回[a]类型的结果,因此f x也必须具有类型[a]。但是在类型签名中,它表示f的类型为t -> a,因此f x必须具有类型a。这导致类型检查器得出结论[a] = a这是一个矛盾并导致您看到的错误消息。

如果您将类型签名更改为flatmap :: (t -> [a]) -> [t] -> [a](或删除它),它将起作用。

相关问题