1

这可能是一个愚蠢的问题,当然不是最好的代码,但我不太明白为什么如果我添加一些打字信息,haskell 会对我大喊大叫

这不起作用(注意 x:a 第 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

而这行得通(注意第 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
4

2 回答 2

6

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

于 2013-09-20T14:21:18.393 回答
5

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

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

于 2013-09-20T14:13:11.737 回答