Взаимная рекурсия в нечетных / четных функциях в haskell

Глава 6 "программирование в Haskell" Грэма Хаттона есть раздел под названием "6.5 взаимная рекурсия", который содержит следующий пример:

even :: Int -> Bool
even 0       = True
even (n + 1) = odd n

odd :: Int -> Bool
odd 0       = False
odd (n + 1) = even n

Я хотел попробовать его. Я ввел код в Hof.файл hs, ran ghci(версия 7.8.3), набрал

:l Hof.hs

и получил следующее сообщение об ошибке

Hof.hs:3:7: Parse error in pattern: n + 1
Failed, modules loaded: none.

почему я получаю это сообщение? Код синтаксически устарел или что-то в этом роде?

2 ответов


N + K шаблоны были удалены от Haskell и больше не доступны. Напишите это так:

even :: Int -> Bool
even 0 = True
even n = odd (n - 1)

odd :: Int -> Bool
odd 0 = False
odd n = even (n - 1)

обратите внимание, что эта функция ужасно не работает для отрицательных входов, поэтому вы, вероятно, хотите увеличить ее с abs.


наш собственный язык довольно мощный. У меня были трудности с ограничениями, когда я учил себя исчислению, пока я не прочитал одно предложение в одном абзаце Ньютона. Разумеется, на английском.

во-первых, вы правы в том, что индексирование не используется или не требуется.

во-вторых, код не знает разницы между четным или нечетным, и вы снова правы, чтобы подвергнуть его сомнению.

наконец, я немного изменил их, чтобы правильно работать на моем реализация.

     evens [x] = [x];    evens (x:xs) = x:odds xs
     odds  [x] = [];      odds (_:xs) =  evens xs

как они работают evens работает. Он создает список вывода. Он берет первый элемент списка, подаваемого ему, и делает его первым или следующим элементом выходного списка. Он зовет odds С остальной частью списка. odds просто возвращает хвост, что он получил обратно в evens.

как хвост, он отбрасывает первый элемент того, что он получает.

evens создает список с примерно половиной отброшенных элементов. odds не производит ничего, кроме критического отбрасывания.

если вы даете evens список [0,1,2,3,4] возвращает все остальные элементы, начиная с 0, то есть [0,2,4]. Если вы даете evens список [1,2,3,4], он возвращает [1,3], потому что список начался с и нечетного числа. Где evens начинается, вот что это производит.

попробуйте либо с [1,1,1,1,1] или "bcdefg"

изменения, внесенные в функции отражают то, что каждый делает соответственно оставшийся элемент. odds отбрасывает его, evens прикрепляет его к концу списка вывода.

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

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

eo s e = [s,s+2..e]