Сохранить текущее продолжение в 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?
Спасибо заранее!
Янник