Сохранить текущее продолжение в SMLofNJ

Я читал эту забавную страницу, объясняющую продолжения в рэкет.

Они представляют код для сохранения текущего продолжения вычислений (и используют этот трюк позже, чтобы реализовать возврат). Код выглядит следующим образом:

(define (currcc)
 (call/cc (lambda (cc) (cc cc))))

Теперь я хотел бы сделать тот же трюк в Standard ML, и, поскольку SML из Нью-Джерси, кажется, единственный интерпретатор, реализующий продолжения, я делаю это там.

Подпись продолжения выглядит следующим образом:

type 'a cont
val callcc : ('a cont -> 'a) -> 'a
val throw : 'a cont -> 'a -> 'b
val isolate : ('a -> unit) -> 'a cont

Прямой перевод будет:

val currcc () = callcc (fn cc => throw cc cc)

но система типов ML запрещает это (поскольку это круговое).

Поэтому я попробовал что-то вроде:

val glcc = ref (isolate (fn x => ()) : unit cont)    
fun savecc () = (callcc (fn (cc : unit cont) => glcc := cc); !glcc)
fun backjump () = throw (!glcc) ();

и другие трюки со ссылками, но я не могу найти способ действительно сохранить текущее продолжение (потому что я изменяю требуемое продолжение с помощью!glcc впоследствии, в этом примере).

Кто-нибудь знает о способе реализации операторов savecc а также backjump что позволило мне сохранить текущее продолжение программы и потом вернуться к этой точке в Standard ML?

Спасибо заранее!

Янник

0 ответов

Другие вопросы по тегам