Взаимная рекурсия в нечетных / четных функциях в 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]