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

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" *)

FLProgClassCategory

grafi/OCamlインタプリタ課題 (最終更新日時 2013-05-14 19:19:04 更新者 grafi)