希望があれば、かつ気が向いたら、チュートリアル的な内容も書くかも知れないです。でもぼくそんな良く分かってないし説明上手じゃないしなあ…。
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" *)