ガード条件で考えられるすべてのパターンを使い果たしdisjoint
ますが、Haskell をPatternMatchFail
実行するとエラーが発生します。
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 の問題が何であるかを推測すると、入力引数に null リストが与えられた場合、期待される引数l@(x:xs) r@(y:ys)
がすでにパターンマッチを呼び出しているということです。PatternMatchFail
まったく同じ条件をチェックするガード条件があるにもかかわらず、null リストになり、結果は になります。最初に「引数条件」で一致する必要があるため、ガード条件に到達することはできません。
ただし、これらの追加の 2 行は、繰り返しが多いので少し不快であり、これを修正するためのより簡潔な方法があるかどうか疑問に思っていました。より一般的には、引数として 3 つ以上のリストを使用する場合、null 条件をチェックするためだけに 3 回以上ばらばらに書き出すことは絶対にしたくないので、そのような場合はどうすればよいでしょうか? お時間をいただきありがとうございます。