我尝试在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”语句与匹配器完整性之间的关系是什么 - 为什么缺少案例?
答案 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
就足够了。 (当然,我们会收到这些模式中发生的所有未使用变量的警告.. :))