Хотя disjoint
исчерпывает все возможные шаблоны в своих режимах защиты, Haskell дает мне ошибку PatternMatchFail
при запуске.Ошибка совпадения шаблонов, когда `function [] _ = ...; function _ [] = ... `синтаксис опущен
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint [email protected](x:xs) [email protected](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 [email protected](x:xs) [email protected](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 в первом случае, это то, что если заданный нулевой список для входного аргумента, его ожидаемые аргументы [email protected](x:xs) [email protected](y:ys)
уже вызывают совпадение шаблонов, которое не является исчерпывающим в случае нулевого списка, что приводит к PatternMatchFail
, несмотря на наличие состояния защиты, которое проверяет точно такое же условие. Он просто не может достигнуть состояния охраны, потому что ему сначала нужно сопоставить «условие аргумента».
Тем не менее, эти дополнительные две линии являются излишним отбрасыванием для меня в их повторяемости, и мне просто интересно, был ли более сжатый способ исправить это. В более общем плане: если бы я использовал три или более списков в качестве аргументов, я определенно не хотел бы выписывать disjoint 3+ больше раз, чтобы проверить нулевые условия, так что я могу сделать в таких случаях? Спасибо за ваше время.
well '(x: xs)' не будет совпадать с пустым списком, очевидно ... так что ваш первый пример просто не исчерпывающий - ** охранники ** только пинают * после * сопоставленного шаблона (в качестве дополнительного. .. well guard - подумайте об этом как 'disjoint l @ (x: xs) ... = если null l then ...') – Carsten