Продолжение прохождения стиля-функциональная композиция


Я изучаю CPS с помощью Racket, и мне удалось записать следующие функции:

;lift a regular single-arg function into CPS
(define (lift/k f)
  (lambda (x k)
    (k (f x))))

;compose two CPS functions
(define (compose/k f g)
  (lambda (x k)
    (g x (lambda (y)
           (f y k)))))

Они, кажется, работают правильно

(define (is-two/k x k)
  (k (= x 2)))
(define is-not-two/k (compose/k (lift/k not) is-two/k))
(is-not-two/k 3 display)
(is-not-two/k 2 display)

#t#f

Мне интересно, являются ли эти функции все еще"истинными CPS". Не испортил ли я" истинное " продолжение-прохождение с этими функциями? Кошерно ли использовать методы функциональной композиции в CPS? Это поощряется? Или это будет считаться "компромиссом"? Есть ли более CPS-y способ сделать это?

Да, я знаю, что только что задал 5 вопросов, но основная идея, стоящая за ними всеми (которую я не уверен, что правильно понимаю), одна и та же. Объяснения в других шепелявит, Хаскель, Эрланг, или другие функциональные языки хорошо.

1 3

1 ответ:

Преобразование типа продолжения-передачи может быть частичным или полным. Вы обычно работаете с системой, где некоторые примитивы ( + , - и т. д.) застряли в ХП-земля. К счастью, CPS работает нормально в любом случае.

Шаги в CPSing:

    Выберите, какие функции будут примитивными. CPS-преобразование так, что все непримитивные функции (включая продолжения) вызываются только в хвостовой позиции.

Итак, в вашем коде ваш 'lift/k' равен по существу, рассматривая его данную функцию как примитивную: обратите внимание, что тело lift/k вызывает 'f' в не-хвостовом положении. Если вы не хотите рассматривать поднятую функцию как примитив, вы должны пойти и переписать ее явно.

Ваша функция "compose" составляет две CPSed-функции, но сама не находится в CPS (то есть вы предполагаете, что "compose" примитивен. Вы, вероятно, хотите, чтобы CPS его. Обратите внимание, что поскольку он просто возвращает значение сразу, это просто:

;compose two CPS functions
(define (compose/k f g k)
  (k (lambda (x k)
       (g x (lambda (y)
              (f y k))))))