在Haskell中键入注释

nic*_*las 1 haskell types

这可能是一个愚蠢的问题,当然不是最好的代码,但我不太明白为什么如果我添加一些打字信息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)

fjh*_*fjh 6

添加到Sebastian Redl的答案:您不能在标准Haskell的函数体中引用顶级定义中的类型变量.但是,有一个名为"Scoped type variables"的GHC扩展允许您这样做(参见http://www.haskell.org/haskellwiki/Scoped_type_variables)


Seb*_*edl 5

(x:a)不是键入信息,它是列表构造函数上的模式匹配,将列表的头部放入其中x,其余部分放入a.

打字信息使用::,无论如何都没有意义,因为a来自主函数类型的占位符在where子句中不可见; 它将是一个独立的类型标识符,因此毫无意义.