Подтвердить что ты не робот

Haskell (n + 1) в сопоставлении с образцом

Я выполнял 99 проблемы в Haskell, когда я столкнулся с solution до Проблема 19, которую я не совсем понял.

Задача состоит в том, чтобы написать функцию rotate, которая работает следующим образом

*Main> rotate ['a','b','c','d','e','f','g','h'] 3
"defghabc"

*Main> rotate ['a','b','c','d','e','f','g','h'] (-2)
"ghabcdef"

Одно из решений -

rotate [] _ = []
rotate l 0 = l
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n
rotate l n = rotate l (length l + n)

Я не понимаю, как совпадение шаблонов может когда-либо достигнуть четвертой строки. Кажется, что это связано с (n+1), так что, когда n отрицательно, третья строка не соответствует, и поэтому четвертая взята. Если это так, то почему обозначение (n+1) работает таким образом, соответственно. разве это не произвольно или это соглашение (по математике?), о котором я не знаю?

Так как я понимаю, это то, что rotate называется рекурсивно в третьей строке с аргументом n, уменьшенным на единицу. Поэтому я думаю, что

rotate [] _ = []
rotate l 0 = l
rotate (x:xs) n = rotate (xs ++ [x]) (n-1)
rotate l n = rotate l (length l + n)

эквивалентен. Однако это не так. Это определение дает следующее предупреждение

Warning: Pattern match(es) are overlapped
         In the definition of `rotate': rotate l n = ...

тогда как прежнее определение компилируется просто отлично.

4b9b3361

Ответ 1

Это конкретный случай того, что называется "n + k patterns", что обычно не нравится, и будет удалены с языка. Подробнее см. здесь.

Здесь - хорошая заметка о шаблонах n + k, которая цитирует следующее из отчета Haskell 98 (выделение мое):

Соответствие шаблону n + k (где n - переменная и k - положительное целое число literal) против значения v успешно, если x >= k, что приводит к связыванию n к x - k, и в противном случае не выполняется. Еще раз, функции >= и - перегружены, в зависимости от типа рисунка. Матч расходится, если сравнение расходится.

Интерпретация букв k является так же, как в числовом литерале шаблонов, за исключением того, что только целое число литералы разрешены.

Итак, n+1 соответствует только если n не менее 1, как вы подозревали. Ваш альтернативный код удаляет это ограничение, что приводит к совпадению совпадений с шаблонами.