Haskell-pattern match (es) перекрываются
test :: String -> String -> Int
test' x y n = n
test' "" (y:ys) n = error "error"
test' (x:xs) "" n = error "error"
test' (x:xs) (y:ys) n =
if x == y
then test' xs ys n
else test' xs ys (n+1)
test a b = test' a b 0
когда я компилирую это, я получаю этот вывод:
Warning: Pattern match(es) are overlapped
и ответ всегда "0", что не то, что я имел в виду. В чем проблема с кодом и как это исправить?
2 ответов
test' x y n = n
будет соответствовать для каждого вызова, другие шаблоны не будут рассматриваться. Я думаю, что это дело должно быть test' "" "" n = n
. Вы получите тот же результат, если переместите исходную строку в конец (когда все остальные случаи терпят неудачу), но тогда вы должны написать test' _ _ n = n
что показывает, что вы намеренно игнорируете некоторые из аргументов.
[Edit]
более коротким решением было бы:
test a b | length a == length b = sum $ map fromEnum $ zipWith (/=) a b
| otherwise = error "error"
на zipWith
выражение создает список из Bool
что это True
для каждого значения. Функция fromEnum
карты False
to 0
и True
to 1
.
шаблоны опробованы по порядку. Первый из ваших шаблонов для test'
всегда совпадает, поэтому этот случай всегда используется. Первый случай, вероятно, должен быть
test' "" "" n = n
вместо.