模式匹配并非详尽无遗

Era*_*ura 3 haskell pattern-matching non-exhaustive-patterns

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

这是我所拥有的:

multiples :: Integer -> [Integer] -> [Integer]
multiples a [] = []
multiples a [b] = filter (\l -> l `mod` a /= 0) [b]
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

我觉得我在第 2 行中遗漏了一些非常简单的东西,但我有点卡住了。我究竟做错了什么?

Ben*_*son 5

欢迎使用堆栈溢出!在您的函数中有几件事情需要修复,但我将从您看起来最困惑的事情开始:这[b]是一个匹配单元素列表的模式,命名其单个 item b。([b, c]将是匹配二元素列表等的模式)它不是匹配任意长bs列表的模式。GHC 告诉你,因为你没有考虑函数被赋予两个或多个元素列表的情况。

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

multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = filter (\b -> b `mod` a /= 0) bs
Run Code Online (Sandbox Code Playgroud)

或者,使用列表理解,

multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = [b | b <- bs, b `mod` a /= 0]
Run Code Online (Sandbox Code Playgroud)

两两件事:我的名字此功能withoutMultiples,因为它过滤掉的倍数a,因为Haskell的功能默认情况下,令行禁止,你可以省略bsfilter版本。

withoutMultiples :: Integer -> [Integer] -> [Integer]
withoutMultiples a = filter (\b -> b `mod` a /= 0)
Run Code Online (Sandbox Code Playgroud)