这可能是一个愚蠢的问题,当然不是最好的代码,但我不太明白为什么如果我添加一些打字信息haskell对我大吼大叫
这不起作用(注意x:第3行):
groupBy3 :: (a -> a -> Bool)-> [a] -> [[a]]
groupBy3 eq = foldr step []
where step (x:a) res =
let (used, res2) = foldr insertel (False, []) res
where insertel (al) (used, acc) =
if used then (True, al:acc)
else if eq x (head al) then
(True, (x:al):acc)
else
(False, al:acc)
in
if used then
res2
else [x]:res
Run Code Online (Sandbox Code Playgroud)
这是有效的(注意第3行的x缺少类型注释)
groupBy3 :: (a -> a -> Bool)-> [a] -> [[a]]
groupBy3 eq = foldr step []
where step x res =
let (used, res2) = foldr insertel (False, []) res
where insertel (al) (used, acc) =
if used then (True, al:acc)
else if eq x (head al) then
(True, (x:al):acc)
else
(False, al:acc)
in
if used then
res2
else [x]:res
Run Code Online (Sandbox Code Playgroud)
添加到Sebastian Redl的答案:您不能在标准Haskell的函数体中引用顶级定义中的类型变量.但是,有一个名为"Scoped type variables"的GHC扩展允许您这样做(参见http://www.haskell.org/haskellwiki/Scoped_type_variables)
(x:a)不是键入信息,它是列表构造函数上的模式匹配,将列表的头部放入其中x,其余部分放入a.
打字信息使用::,无论如何都没有意义,因为a来自主函数类型的占位符在where子句中不可见; 它将是一个独立的类型标识符,因此毫无意义.