2012-03-31 2 views
4

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

data Nat = Zero | Succ Nat 

Мы используем RAT здесь, потому что набор значений должен быть бесконечным, и я знаю, что принцип заключается в том, чтобы выразить каждое новое значение с точки зрения предыдущий, но я не понимаю, как это образует натуральные числа. Кто-то умнул бы это очистить? Благодаря

+7

Перевести 'Succ' на' 1 + '. Каждое натуральное число равно 1 + (1 + (... (1 + 0) ...)) 'для подходящего числа операций. –

ответ

14

Это утверждает, что:

  • Nat тип.

  • Zero имеет тип Nat. Это представляет собой натуральное число 0.

  • Если n имеет тип Nat, то Succ n имеет тип Nat. Это представляет собой натуральное число n +1.

Так, например, Succ (Succ Zero) представляет собой 2, 3 представляет Succ (Succ (Succ Zero)), Succ (Succ (Succ (Succ Zero))) представляет 4, и так далее. (Эта система определения натуральных чисел от 0 и преемников называют Peano axioms.)

В самом деле, Zero и Succ просто специальные виды функций (конструкторы), объявленные для создания Nat значения:

Zero :: Nat 
Succ :: Nat -> Nat 

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

predecessor :: Nat -> Nat 
predecessor Zero = Zero 
predecessor (Succ n) = n 

Ничто об этом не относится к рекурсивным алгебраическим типам данных, конечно, только к алгебраическим типам данных; но простой факт, что тип алгебраических данных может иметь значение того же типа, что и одно из его полей, является тем, что создает здесь рекурсию.

+0

Спасибо за такой ясный ответ. Таким образом, конструктор Succ имеет встроенную функцию, представляющую n + 1? Я был смущен, потому что думал, что это просто декларирует другую возможную ценность в обычном режиме. Если у нас есть число n, то почему мы хотим представить значение n + 1, то есть следующее значение в последовательности натуральных чисел? Разве мы не просто озабочены тем, как мы можем выразить значение n? Спасибо за бит соответствия шаблону в конце - это было очень полезно! – user1058210

+0

Нет, он не встроен; вы можете переименовать его в «Fnarf», и все будет точно так же. Идея состоит в том, что мы определяем этот тип и присваиваем каждому значению его значение * означает натуральное число: мы * представляем * данные с типом. 'Succ n' представляет * n * + 1, потому что * n * уже должен быть представлен * другим *' Nat'. Если у вас есть «Zero» (0), и вы хотите 1, вам нужно использовать «Succ Zero», чтобы представлять 0 + 1 = 1. Если у вас есть «Succ Zero» (1), и вы хотите 2, у вас есть для использования 'Succ (Succ Zero)', для представления 1 + 1 = 2 ... и так далее. – ehird

+3

@ user1058210 Нет, Succ не встроен. Это просто имя, которое вы дали конструктору. Вам нужен способ получить от 'n' до' n + 1', чтобы вы могли представлять любое число. Если определение было просто «data Nat = Zero», вы могли бы представлять только ноль.Конечно, вы можете расширить это до большего числа чисел, таких как 'data Nat = Zero | Один | Два', но этот подход дает только конечное число чисел. Используя Succ, вы можете просто применить 'Succ' к' Zero' 'n' раз, чтобы представить номер' n'. – sepp2k

Смежные вопросы