非详尽模式的例外情况

时间:2017-02-05 07:37:02

标签: haskell

我尝试在GHCi中运行这种简洁明了的quicksort实现:

:{
qs(x:xs) = qs left ++ [x] ++ qs right
  where left = [ y | y <- xs, y < x]
        right = [ y | y <- xs, y >= x ]
:}
print $ qs [1,123,42,90,24,12,3]

结果是:

*** Exception: <interactive>:(38,1)-(40,42): Non-exhaustive patterns in function qs

“where”语句与匹配器完整性之间的关系是什么 - 为什么缺少案例?

2 个答案:

答案 0 :(得分:5)

错误消息Non-exhaustive patterns in function qs表示qs的模式匹配并不涵盖qs接受的所有输入范围。在这种情况下,您将缺少空列表的大小写。

:{
qs [] = []
qs (x:xs) = qs left ++ [x] ++ qs right
  where left = [ y | y <- xs, y < x]
        right = [ y | y <- xs, y >= x ]
:}

答案 1 :(得分:3)

正如亚历克所说,你忘了处理空名单案件。

为避免将来出现此类错误,我强烈建议您使用-Wall打开警告。这样做可以使GHC检查模式在编译时是否是详尽的(定义时间)。

Prelude> :set -Wall
Prelude> :{
Prelude| qs(x:xs) = qs left ++ [x] ++ qs right
Prelude|   where left = [ y | y <- xs, y < x]
Prelude|         right = [ y | y <- xs, y >= x ]
Prelude| :}

<interactive>:12:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for ‘qs’: Patterns not matched: []

如您所见,它指出[]未匹配。

这是另一个例子,我们处理空列表和以x,y开头的列表,但是我们忘记处理包含一个元素的列表(格式为[_])。< / p>

Prelude> :{
Prelude| f [] = 0
Prelude| f (x:y:xs) = 0
Prelude| :}

<interactive>:18:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for ‘f’: Patterns not matched: [_]

添加f [x] = 0就足够了。 (当然,我们会收到这些模式中发生的所有未使用变量的警告.. :))