uncaught exception TopLevelCallcc
上のエントリに書いたcallccの例が、SML/NJでどうなるのか確かめようと思って試したら
Standard ML of New Jersey, Version 110.0.7, September 28, 2000 [CM; autoload enabled] - fun mycallcc f = SMLofNJ.Cont.callcc (fn k => f (SMLofNJ.Cont.throw k)) ; val mycallcc = fn : (('a -> 'b) -> 'a) -> 'a - datatype r = R of (r -> r) | I of int ; datatype r = I of int | R of r -> r - val x = mycallcc (fn k1 => mycallcc (fn k2 => k1 (R k2))) ; val x = R fn : r - case x of R k => k (I 123) ; stdIn:20.1-20.27 Warning: match nonexhaustive R k => ... uncaught exception TopLevelCallcc raised at: build/compile.sml:378.30-378.44 -
となった。SML/NJではトップレベルを跨ぐ継続は扱えないらしい。
- val y = ref (fn x => x + 1) ; val y = ref fn : (int -> int) ref - mycallcc (fn k => (y := k; 123)) ; val it = 123 : int - !y 456 ; uncaught exception TopLevelCallcc raised at: build/compile.sml:378.30-378.44 -
なお、SML/NJのcallccは、Standard MLにはない独自拡張。また、(標準の)OCamlにはcallccはない。
追記:Leroyのcallccライブラリを利用した、OCamlでの実験。
# #load "callcc.cma" ;; # let mycallcc f = Callcc.callcc (fun k -> f (Callcc.throw k)) ;; val mycallcc : (('a -> 'b) -> 'a) -> 'a = <fun> # type r = R of (r -> r) | I of int ;; type r = R of (r -> r) | I of int # let x = mycallcc (fun k1 -> mycallcc (fun k2 -> k1 (R k2))) ;; val x : r = R <fun> # match x with R k -> k (I 123) ;; Characters 0-29: Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: I _ match x with R k -> k (I 123) ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ val x : r = I 123 #
callccとletだけでxの値がちゃんと(?)変わりました。