2011-10-04 6 views
7
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 

Когда я компилирую это, я получаю этот выход:Haskell - матч шаблон (ы) накладываются друг на друга

Warning: Pattern match(es) are overlapped 

И ответ всегда «0», который является не то, что я намеревался. В чем проблема с кодом и как его исправить?

ответ

9

test' x y n = n будет соответствовать каждому звонку, другие образцы не будут рассматриваться. Я думаю, что этот случай должен быть test' "" "" n = n. Вы получите тот же результат, если переместите исходную строку на конец (когда все остальные случаи сбой), но тогда вы должны написать 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.

+0

Очень полезно! Я многому научился! благодаря – Ferry

7

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

test' "" "" n = n 

вместо этого.

Смежные вопросы