2016-12-18 9 views
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でエラーになります:私はむしろ記述します。私は何が欠けていますか?

答えて

1

私はあなたの例

(val factorial 
    (lambda (x) 
    (if (= x 0) 
     1 
     (* x (factorial (- x 1))))) 
(factorial 6)) 

が間違っていると信じています。コードを正しく理解すると、valは再帰的バインディングを導入しないため、内部のfactorialはバインドされません。そして、通訳者はあなたにそのエラーを与えます。

代わりにこのプログラムを試してみてください。

(def factorial 
    (lambda (x) 
    (if (= x 0) 
     1 
     (* x (factorial (- x 1))))) 
(factorial 6)) 
関連する問題