Ошибка «Несколько объявлений» при сопоставлении шаблона с подстановочным знаком

В учебных целях я пытаюсь написать собственную реализацию функции zipWith. Однако я сталкиваюсь с проблемой сопоставления шаблонов в крайних случаях с _. Сначала я опишу хороший случай, затем плохой. Надеюсь, кто-нибудь сможет объяснить, почему они ведут себя по-разному. Спасибо

Если я пишу функцию zipWith следующим образом, она работает (обратите внимание на порядок крайних случаев, соответствующих пустому списку в строках 2 и 3): -

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipwith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

Компиляция в GHCI: -

ghci> :l ZipWith.hs 
[1 of 1] Compiling Main             ( ZipWith.hs, interpreted )

Хорошо, вышесказанное в порядке, но если я поменяю сопоставление с образцом для крайних случаев вокруг GHCI, выдаст ошибку «Несколько объявлений» для строк 2 и 4.

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ _ [] = []
zipwith' _ [] _ = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

Компиляция в GHCI: -

ZipWith.hs:4:0:
    Multiple declarations of `Main.zipWith''
    Declared at: ZipWith.hs:2:0
                 ZipWith.hs:4:0
Failed, modules loaded: none.

я в тупике...

  1. Глядя на шаблоны в строках 2 и 4, они кажутся взаимоисключающими, но я явно упускаю здесь что-то фундаментальное.
  2. Почему переключение шаблонов в строках 2 и 3 может привести к исчезновению ошибки компиляции.

person Jabbslad    schedule 31.01.2011    source источник


Ответы (1)


Сообщение об ошибке жалуется не на перекрывающиеся шаблоны (ваши шаблоны действительно перекрываются в случае двух пустых списков, но это не проблема и не проблема), а несколько определений функции zipWith.

Причина этого в том, что во втором случае у вас есть одно определение zipWith, за которым следует несвязанное определение zipwith (обратите внимание на нижний регистр w), за которым следует новое, конфликтующее определение zipWith. Другими словами, это простая опечатка. (Мне потребовалось некоторое время, чтобы увидеть - довольно хитрая опечатка)

person sepp2k    schedule 31.01.2011
comment
О, чувак, эта опечатка так смущает меня, спасибо, что заметил ее, а также объяснил мою неправильную интерпретацию ошибки. - person Jabbslad; 01.02.2011
comment
+1 как за вопрос, так и за ответ. Кто-то наверняка найдет это в Google и захочет увидеть этот ответ. - person Dan Burton; 01.02.2011
comment
Они действительно должны добавить что-то вроде возможной опечатки в сообщение об ошибке. - person fuz; 01.02.2011