2013-03-23 4 views
10

У меня есть функция с двумя аргументами, которые мне нужно сопоставить. Если я использую каррирование на первом шаблоне он не будет компилироваться:Почему я могу заархивировать один из шаблонов, но не другой в моем шаблоне?

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- ghci: "Equations for drop' have different numbers of arguments" 
    drop' n (x:xs) = drop' (n-1) xs 

Компилятор дает этот вывод:

99.hs:106:3: 
Equations for drop' have different numbers of arguments 
    99.hs:106:3-15 
    99.hs:107:3-33 
In an equation for `split': 
    split xs n 
     = (take' n xs, drop' n xs) 
     where 
      take' 0 _ = [] 
      take' n (x : xs) = x : take (n - 1) xs 
      drop' 0 = id 
      drop' n (x : xs) = drop' (n - 1) xs 
Failed, modules loaded: none. 

Если бы я только дать выделанной картины, однако затем она составляет:

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- compiles 

Что дает?

+1

Предполагая, что вы знаете, что можете просто написать 'drop '0 x = x'? – Koterpillar

+3

Все уравнения, определяющие функцию, должны иметь одинаковое количество аргументов. Поэтому 'drop 0 = id; drop n = \ (_: xs) -> drop (n-1) xs' будет компилироваться. –

+4

[Обратите внимание, что все предложения, определяющие функцию, должны быть смежными **, а количество шаблонов в каждом предложении должно быть одинаковым. **] (http://www.haskell.org/onlinereport/haskell2010/haskellch4.html# x10-830004.4.3) –

ответ

10

Единственное объяснение, которое я мог бы найти (http://www.haskell.org/pipermail/haskell-cafe/2009-March/058456.html):

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

+0

Мне кажется, что многие мысли попали в различные отчеты Haskell о том, как защитить от ошибок программиста, не жертвуя тем, что вы можете выразить на этом языке. См. Также комментарий Даниэля Фишера, и даже страшное ограничение мономорфизма относится к этой категории. Сейчас немного хлопот, но позже вы будете благодарны за это. – yatima2975

+0

@ yatima2975 Я могу понять, что нужно забивать ошибки обычного программиста в зародыше. Но разве это не могло быть предупреждением компилятора? Хотя я думаю, что наличие кучи предупреждений компилятора тоже может раздражать (не говоря уже о потенциальных аннотации для их подавления), поэтому я думаю, что это достойный компромисс, так как я не могу представить случай, когда код будет значительно менее выразительным с это небольшое ограничение. – Guildenstern

1

Я не могу сказать вам , почему точно, но это известное ограничение. Все случаи одной и той же функции должны иметь одинаковое количество аргументов.

1

Это раздражает «особенность» GHC, чтобы быть уверенным, но чтобы исправить это, вы можете сделать это:

drop' n = \(x:xs) -> drop' (n-1) xs 

Вы не снискать оба или ни, и оба к тому же количество аргументов. Если это проверка на линт, это здорово: но я хочу, чтобы была опция компилятора для включения/выключения.

+2

Поскольку это идентично другому определению (и на самом деле более подробному), он поражает точку немного ИМХО. – jozefg

+0

@jozefg Я разместил это, потому что я не мог понять другие ответы без дальнейшего расследования: альтернативная точка зрения часто полезна. – jpaugh