代码之家  ›  专栏  ›  技术社区  ›  Mantas Vidutis

Haskell平面图

  •  11
  • Mantas Vidutis  · 技术社区  · 16 年前

    flatmap :: (t -> a) -> [t] -> [a]  
    flatmap _ [] = []  
    flatmap f (x:xs) = f x : flatmap f xs  
    

    它实现了“map”部分而不是“flat”。
    我所做的大多数修改都会导致令人沮丧和相当缺乏信息

    Occurs check: cannot construct the infinite type: a = [a]  
        When generalising the type(s) for `flatmap' 
    

    错误。

    我错过了什么?

    1 回复  |  直到 16 年前
        1
  •  23
  •   sepp2k    16 年前

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

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

    类型检查器看到您对 f x 和 flatmap f xs . 自 ++ 在两个相同类型的列表上工作时,类型检查器现在知道两个表达式都必须计算为相同类型的列表。现在打字员也知道了 平面图f xs 将返回类型为的结果 [a] ,所以 也要有类型 [答] . 但是在类型签名中,它表示f具有类型 t -> a f x公司 a . 这导致类型检查器得出结论 [a] = a 这是一个矛盾,并导致您看到的错误消息。

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