2
scalaのスキーム言語のインタープリタを実装する次のコードを提供します。scalaのスキームインタープリタでの再帰の処理
(val factorial (lambda (x)
(if (= x 0) 1 (* x (factorial (- x 1)))))
(factorial 6))
はので、私は次の更新与えられていませんとするには、次の
def evalRec(x: Data, env: Env): Data = {
x match {
case i: Int => i
case Symbol(s) => env(s) match {
case Some(v) => v
case None => sys.error("Unknown symbol " + s)
}
case List('lambda, params: List[Data], body) =>
((args: List[Data]) => {
val paramBinding = params.map(_.asInstanceOf[Symbol].name).zip(args)
evalRec(body, updateEnv(env, paramBinding))
})
case List('val, Symbol(s), expr, rest) =>
evalRec(rest, updateEnv(env, List(s -> evalRec(expr, env))))
case List('def, Symbol(s), expr, rest) => {
evalRec(rest, updateEnvRec(env, s, expr))
}
case List('if, bE, trueCase, falseCase) =>
if (evalRec(bE, env) != 0) evalRec(trueCase, env)
else evalRec(falseCase, env)
case opE :: argsE => {
val op = evalRec(opE, env).asInstanceOf[List[Data] => Data]
val args: List[Data] = argsE.map((arg: Data) => evalRec(arg, env))
op(args)
}
}
}
のような式を処理され、このコードの目的:関連する例はupdateEnvRecまたはupdateEnvへの呼び出しを含むものです環境の定義:
:type Env = String => Option[Data]
val recEnv : Env = ((id:String) => funEnv.get(id))
def updateEnv(env : Env, bindings : List[(String,Data)]) : Env = bindings match {
case Nil => env
case (id,d)::rest => ((x:String) =>
if (x==id) Some(d)
else updateEnv(env,rest)(x))
}
def updateEnvRec(env: Env, s : String, expr : Data) : Env = {
def newEnv : Env = ((id:String) =>
if (id==s) Some(evalRec(expr, newEnv))
else env(id)
)
newEnv
}
私の問題は、私は理由を呼び出して理解していないということです
作品。最初の戦略と私が最初にevalRec(expr, env)
を評価しなければならない
evalRec(rest, updateEnvRec(env,s,expr))
ので、これは階乗含まれていませんので、その点のENVでエラーになります:私はむしろ記述します。私は何が欠けていますか?