Haskell 使用as模式时的非穷举模式
我正在尝试使用foldr实现我自己的groupBy函数(类似于Prelude的函数) 以下定义似乎有效: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)
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