模式匹配并非详尽无遗

时间:2016-09-17 23:39:22

标签: haskell pattern-matching non-exhaustive-patterns

我正在尝试创建一个函数,它从整数列表中消除给定Integer的倍数,格式为multiples x [y],其中x是给定的整数,y是列表。

这就是我所拥有的:

multiples :: Integer -> [Integer] -> [Integer]
multiples a [] = []
multiples a [b] = filter (\l -> l `mod` a /= 0) [b]
调用

multiples会失败,说“功能倍数中的非详尽模式”。所以我在我的文件中使用ghci -Wall来查看缺少哪些模式,并返回:

multiples.hs:2:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `multiples': Patterns not matched: _ (_:_:_)

multiples.hs:2:11: warning: [-Wunused-matches]
    Defined but not used: `a'

我觉得我错过了第2行非常简单的东西,但我有点卡住了。我做错了什么?

2 个答案:

答案 0 :(得分:4)

你的模式

    multiples a [b]

期望一个Integer(绑定到名称“a”)和包含一个元素(绑定到名称“b”)的Integer列表。在此模式中删除方括号(将“b”的类型更改为[Integer]),它应该正常工作。你也可以把这个功能用于形成

    multiples a = filter (\l -> l `mod` a /= 0)

并省略第一个模式,因为它应该被过滤函数覆盖。

答案 1 :(得分:4)

欢迎使用Stack Overflow!在你的函数中有几个要修复的东西,但我会从你看起来最困惑的那个开始:这里[b]是一个匹配 one-element 列表的模式,命名其单个项b。 ([b, c]将是匹配双元素列表的模式,等等。)它不是匹配任意长b列表的模式。 GHC告诉你,因为你还没有考虑到函数被赋予了两个或更多元素列表的情况。

如果要匹配b的任意列表,请省略方括号。此外,您的函数的第一行不是必需的,因为第二行已经处理了这种情况。

multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = filter (\b -> b `mod` a /= 0) bs

或者,使用列表理解,

multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = [b | b <- bs, b `mod` a /= 0]

还有两件事:我将此函数命名为withoutMultiples,因为它过滤掉 a的倍数,并且因为Haskell函数默认为curry,所以可以省略{ {1}}版本中的{1}}。

bs