Ошибка «Несколько объявлений» при сопоставлении с шаблоном - PullRequest
10 голосов
/ 01 февраля 2011

В целях обучения я пытаюсь написать собственную реализацию функции 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 приводит к исчезновению ошибки компиляции.

1 Ответ

17 голосов
/ 01 февраля 2011

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

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

...