私はいくつかの話題について疑問を抱いています。つまり、Ocamlには静的スコープと動的スコープの両方のインタープリタを記述する必要があります。 今のところ私は、環境(IDE *値)リストとeval(evn * exp)を使用して静的スコープを持つバージョンを実装し、ステートメントのときにevnを渡しました。OCamlレキシカル対ダイナミックスコープ
質問は、リストの読み方を変更することによって、リストとそのような評価関数の両方をスコープ(動的 - 静的)とするか、別の方法をとる必要がありますか?ここで
コードの一部:
type ide = string
type bi_operator =
Plus
|Minus
|Mul
|Div
|Eq
|LThan
|LEq
|And
|Or
type exp =
Var of ide
|Const of value
|Fun of ide * exp
|Not of exp
|BOp of exp * bi_operator * exp
|Let of ide * exp * exp
|If of exp * exp * exp
|FunApp of exp * exp
and value =
| Int of int
| Bool of bool
| Closure of env * string * exp
and env = (ide * value) list
評価コード:
let rec eval (evn,e) = match e with
| Const _ -> expToV(e)
| Var x -> lookup (x,evn)
| BOp (a,b,c) -> (match ((eval(evn,a)),(eval(evn,c))) with
| (Int a, Int c) ->
(match b with
| Plus -> Int (a + c)
| Minus -> Int (a - c)
| Mul -> Int (a * c)
| Div -> Int (a/c)
| Eq -> Bool (a = c)
| LThan -> Bool (a < c)
| LEq -> Bool (a <= c)
| _ -> raise (MLFailure "Not a valid Int operator")
)
| (Bool a, Bool c) ->
(match b with
| Eq -> Bool (a = c)
| And -> Bool (a && c)
| Or -> Bool (a || c)
| _ -> raise (MLFailure "Not a valid Bool operator")
)
| _ -> raise (MLFailure "Bin arguments do not match"))
| Fun (a,b) -> Closure (evn,a,b)
| Not (a) -> (match (eval(evn,a)) with
| (Bool a) -> if(a = false) then Bool(true) else Bool(false)
| _ -> raise (MLFailure "Bin arguments do not match"))
| Let (a,b,c) -> eval (((a,eval (evn,b))::evn) , c)
| If (a,b,c) -> if (eval (evn,a) = (Bool true)) then (eval (evn,b)) else (eval (evn,c))
| FunApp (a,b) -> (match eval (evn,a) with
| Closure (environment,funct,args) -> eval (((funct, eval (evn,b))::environment),args)
| _ -> raise (MLFailure "Bin arguments do not match"))
ここの文を作る私の例:
let _ = eval ([("x", Int 3);("t", Int 5);("z", Int 5);("x", Int 5);("y", Int 1)], (Let ("x", Const (Int 1),
Let ("f", Fun ("y", Var "x"),
Let ("x", Const (Int 2), FunApp (Var "f", Const(Int 0)))))));;
それとも
let _ = eval ([], (Let ("x", Const (Int 1),
Let ("f", Fun ("y", Var "x"),
Let ("x", Const (Int 2), FunApp (Var "f", Const(Int 0)))))));;
これらの例では
結果は、この例が与える私の本の中でのInt 1 です:
字句:のInt 1
ダイナミックます。int 2つの
その正しい 実装を探します。
ダイナミックスコープでもenvリストを使用できます。静的スコープを正しく行っていれば、動的スコープを「バグ」として簡単に実装して、クロージャから環境を取り除くことができます。 – camlspotter
camlspotterのコメントは実際の回答ですが、OCamlの最小限のコードを入れてください。より具体的な回答を –