Церковные цифры Алонзо в SML
У меня есть задание, которое включает в себя создание церковных цифр в SML. Я посмотрел вокруг и просто не могу найти, что я делаю не так. Цель состоит в том, чтобы сделать функцию, которая принимает int и возвращает церковную цифру, определенную как тип данных 'цифра = Num of ('a -> 'a) -> 'a -> 'a (которая предопределена моим учителем), Затем создать вторую функцию, которая принимает церковную цифру и возвращает int.
Я видел предыдущий пост с кодом:
val ZERO = C(fn (f,x) => x)
fun subCreate 0 (f,x) = x
| subCreate n (f,x) = f (subCreate (n-1) (f,x))
fun create n = C(fn (f,x) => subCreate n (f,x));
fun churchToInt (c, cn) = cn ((fn x => x+1), 0) 0;
но это не работает и дает ошибочные типы переменных, не обобщенные из-за ограничения значений, создаются для фиктивных типов.
Когда я использовал код:
val zero = fn s => fn x => x;
(определить ноль), а затем
val next = fn n => fn s => fn x => (f ((n s) x));
(просто чтобы проверить, смогу ли я увеличить ноль, прежде чем настраивать итеративную или рекурсивную функцию), я получил ту же ошибку. Я потратил часы на эту проблему, не в состоянии представить церковную цифру. Может ли кто-нибудь указать мне правильное направление?
1 ответ
Я думаю, что вы столкнулись с "ценностным полиморфизмом" в SML'97. Вот очень длинный раздел документации, обсуждающий это.
Одним из обходных путей является, когда у вас есть выражение, которое вызывает эту проблему, например, next zero
оберните вокруг него функцию, например fn x => next zero x
,
Я думаю, вы могли бы сделать еще одну вещь, вместо того, чтобы оценивать определения на верхнем уровне интерпретатора, обернуть определение и весь код, который использует его, в локальную область (например, внутри let ... in ... end
) или в функции.