尽管disjoint
在其保护条件中耗尽了所有可能的模式,但 HaskellPatternMatchFail
在运行它时给了我一个错误。
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint l@(x:xs) r@(y:ys)
| null l || null r = True
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
-- | Terminates when either list has been reduced to null, or when their head
-- elements are equal. Since lists are ordered, it only needs to compare head elements.
但是,如果我写它没有问题:
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint [] _ = True
disjoint _ [] = True
disjoint l@(x:xs) r@(y:ys)
-- | null l || null r = True -- now redundant, but included for sake of continuity
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
如果没有这些额外的行,我会得到一个PatternMatchFail
. 如果我要推断在第一种情况下 Haskell 的问题是什么,那就是如果给定一个输入参数的空列表,它的预期参数l@(x:xs) r@(y:ys)
已经在调用模式匹配,在这种情况下是非详尽的一个空列表,PatternMatchFail
尽管有一个检查完全相同的条件的保护条件,但结果是 a 。它永远无法达到保护条件,因为它首先需要匹配“参数条件”。
然而,那些额外的两行重复性让我有点反感,我只是想知道是否有更简洁的方法来解决这个问题。更一般地说:如果我要使用三个或更多列表作为参数,我绝对不想再写出不相交的 3 次以上来检查空条件,那么在这种情况下我该怎么办?感谢您的时间。