Haskell 使用as模式时的非穷举模式

Haskell 使用as模式时的非穷举模式,haskell,Haskell,我正在尝试使用foldr实现我自己的groupBy函数(类似于Prelude的函数) 以下定义似乎有效: myGroupBy p xs = foldr step [] xs where step x acc | null acc = [[x]] | p x (head (head acc)) = (x:head acc):(tail acc)

我正在尝试使用foldr实现我自己的groupBy函数(类似于Prelude的函数)

以下定义似乎有效:

myGroupBy p xs = foldr step [] xs
                  where step x acc
                          | null acc = [[x]]
                          | p x (head (head acc)) = (x:head acc):(tail acc)
                          | otherwise = [x]:acc
因为我多次使用
head acc/tail acc
,尽管我可以通过使用as模式来改进它。所以我把它改成:

myGroupByNew p xs = foldr step [] xs
                  where step x acc@(a:b)
                          | null acc = [[x]]
                          | null b = [[x]]
                          | p x (head a) = (x:a):b
                          | otherwise = [x]:acc
然而,这种方法现在给了我一个非穷举模式错误。我无法理解,我已经检查了
null acc
null b
,因此假设
a
不能为null。对于x,在前面的方法中也没有为它设置任何保护子句

我有点不知所措,我缺少的模式是什么。

acc@(a:b)
只会匹配非空列表。
@
只是为值提供了一个别名,但模式仍然需要匹配

就好像你有这样一个功能(尽管是以一种更聪明的方式):

如果调用
步骤x[]

对评论作出答复:

step x null = [[x]]
提供冗余匹配,因为
null
是检查空列表的函数。它不是数据构造函数,因此在模式匹配中使用名称只是一个“通配符”(它总是匹配)。 您想要匹配空数据构造函数
[]

尝试:


我认为如果
acc
[]
,它将不匹配模式
(a:b)
,因此可能缺少的模式是
步骤x[]
acc=[]
null acc
@peeyussingh覆盖,但该检查仅在
acc@(a:b)
模式匹配后执行,所以它没有帮助。这些天有点太容易触发了…不知道为什么这个问题被否决了…一个小建议:打开警告应该在编译时报告
步骤
不会处理空列表
[]
。建议。理解,但如果我在定义的其余部分之前包括
步骤x null=[[x]]]
单独检查
null acc
(a:b)…,则我会得到一个过度匹配异常。您能告诉我如何重新编写它吗?谢谢,这很管用,之前已经尝试了
步骤x null
(这显然是错误的)。。。
step x null = [[x]]
step x [] = [[x]]
step x acc@(a:b)
  | null b = [[x]]
  | p x (head a) = (x:a):b
  | otherwise = [x]:acc