使用模式时的非详尽模式

时间:2018-10-09 03:01:55

标签: haskell

我正在尝试使用文件夹实现自己的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-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

但是,此方法现在给我一个非穷尽的模式错误。我无法理解,我已经检查了null accnull b,因此假设a不能为null。至于x,也没有在前面的方法中为其添加任何保护子句。

我有点迷失了我所缺少的模式。

1 个答案:

答案 0 :(得分:7)

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

好像您具有这样的功能(尽管以一种更聪明的方式):

step x (a:b) = 
  let acc = (a:b) in
  ....

您可以在此处清楚地看到,如果您致电step

step x []将永远不匹配

回复评论:

step x null = [[x]]

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

尝试:

step x [] = [[x]]
step x acc@(a:b)
  | null b = [[x]]
  | p x (head a) = (x:a):b
  | otherwise = [x]:acc