Haskell - Паттерны совпадений совпадают - PullRequest
7 голосов
/ 04 октября 2011
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 ]

9 голосов
/ 04 октября 2011

test' x y n = n будет соответствовать для каждого вызова, другие шаблоны не будут рассматриваться.Я думаю, что этот случай должен быть test' "" "" n = n.Вы получите тот же результат, если переместите исходную строку на end (когда все другие случаи не пройдены), но тогда вам следует написать test' _ _ n = n, что показывает, что вы намеренно игнорировали некоторые аргументы.

[Редактировать]

Более короткое решение было бы:

test a b | length a == length b = sum $ map fromEnum $ zipWith (/=) a b
         | otherwise = error "error" 

Выражение zipWith создает список Bool, который равен Trueза каждую разницу.Функция fromEnum отображает False на 0 и True на 1.

7 голосов
/ 04 октября 2011

Шаблоны пробуются по порядку. Первый из ваших шаблонов для test' всегда совпадает, поэтому всегда используется регистр. Первый случай, вероятно, должен быть

test' "" "" n = n

вместо.

...