[haskell] [ru_lambda] Как сделать вычитание нумералов Чёрча?
От: Кодт Россия  
Дата: 25.12.08 10:33
Оценка:
http://community.livejournal.com/ru_lambda/95113.html

А как можно определить операцию minus, для простой реализации лямбда исчисленя на хаскеле?
Проблема в том, что выражения вида pred (pred three) прекрасно работают, а вот для эквивалентного two pred three, автоматом тип уже не выводится.




Декремент определяется так
pred cn f x = fst (cn (\(i,j)->(j,f i)) xx) where
  xx = (x,x) -- тогда pred zero == zero
  -- либо
  xx = (error "ушли в минус",x) -- тогда pred zero = (_|_)

В исходном варианте он определяется на ленивой паре, if selector then first_part else second_part, ну это не очень принципиально.

Проблема не в ограниченности вывода типов.
Обычно нумерал имеет тип
type CN t = (t->t)->t->t

zero :: CN t -- хотя это просто канцелятор : (flip const) :: t1->t2->t2
one  :: CN t -- хотя это просто аппликатор : (.) :: (t1->t2)->t1->t2

А здесь мы видим, что
pred :: (CN (t,t)) -> (CN t)

На самом деле, конечно, :t pred покажет, что там задействована туча типов — но это лишь от лишней общности формулы, точно так же, как в случае с zero и one.

Вот тут и затаилось западло: pred не замкнут, значит, он не подходит как аргумент для нумерала в функции вычитания a `minus` b = b pred a
Вот если бы объявить
type CN = forall t . (t->t)->t->t -- за синтаксис не ручаюсь

или что-то в таком роде... Тут я, к сожалению, не копенгаген.
То есть, нужно сделать стирание типа — но не полностью на всё лямбда-исчисление, а прицельно на нумералы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.