希望があれば、かつ気が向いたら、チュートリアル的な内容も書くかも知れないです。でもぼくそんな良く分かってないし説明上手じゃないしなあ…。
Lazyを使った再帰的環境
OCamlでもlazyというキーワードを使えば実は遅延評価ができるのですが、これでも再帰関数を実装できそうです。試しに書いてみた以下のコードが動作しました。Haskellではデータ構造が遅延評価して,かつ再帰的に自分を中に入れるようなデータが書けるので、http://www.haskell.org/haskellwiki/Tying_the_Knotに書いてるようにループを含むようなデータ構造が作れるのですが、同じようなことをOCamlでやってみた感じです。
Scheme演習でもちらっと出てきたように、クロージャを使えば遅延評価は実現できるので、結局スライドに書いてたクロージャを使うやり方と同じことだとは思います。でもlazy使うほうが書きやすそう。
type expr = EDummy
type value = VFun of (env lazy_t) * (string list) * expr
and frame = (string * value) list
and env = frame list
let rec lookup key = function
| [] -> raise Not_found
| frame::env -> try List.assoc key frame with Not_found -> lookup key env
let rec env =
(
("fuga", VFun ((lazy env), [], EDummy)) ::
("hoge", VFun ((lazy env), ["foo"; "bar"], EDummy)) ::
[]
) :: []
let _ = match (lookup "hoge" env) with
(VFun (lazy env', _, _)) ->
match (lookup "fuga" env') with
(VFun (lazy env'', _, _)) ->
match (lookup "hoge" env'') with
(VFun (_, [x; y], _)) ->
print_string (x^y) (* print "foobar" *)
