我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)
由于我head acc/tail acc多次使用,虽然我可以通过使用as-pattern来改进它.所以我改为:
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
Run Code Online (Sandbox Code Playgroud)
但是,这种方法现在给了我一个非详尽的模式错误.我不明白,我已经检查null acc和null b,所以假设a不能为空.至于x,也没有在前面的方法中为它添加任何保护条款.
我有点迷失了我所缺少的模式.
acc@(a:b)只会匹配非空列表.在@刚刚给出了值的别名,但图案仍需要匹配.
它好像你有这样的功能(虽然以更聪明的方式):
step x (a:b) =
let acc = (a:b) in
....
Run Code Online (Sandbox Code Playgroud)
step如果你打电话,你可以清楚地看到这里永远不会匹配step x []
回应评论:
step x null = [[x]]
Run Code Online (Sandbox Code Playgroud)
提供冗余匹配,因为它null是一个检查空列表的函数.它不是数据构造函数,因此在模式匹配中使用名称只是一个"通配符"(它总是匹配).您想匹配空数据构造函数[].
尝试:
step x [] = [[x]]
step x acc@(a:b)
| null b = [[x]]
| p x (head a) = (x:a):b
| otherwise = [x]:acc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |