问题描述
在这里,我根据涉及Scala中处理环境的两个规则编写了代码。 一切都可以在代码中完美地完成,但是我对我为解释幕后发生的事情而编写的定义不太自信。我不确定是否有人可以查看我的规则是否正确?我对翻译语义规则没有信心。对于第二条规则,我了解到无效变量将导致评估错误。我不清楚应该在哪个规则1中定义。
sealed trait Environment
sealed trait Value
case object EmptyEnv extends Environment
case class Extend(x: String,v: Value,sigma: Environment) extends Environment
case class ExtendRec(f: String,x: String,e: Expr,sigma: Environment ) extends Environment
case class ExtendMutualRec2(f1: String,x1: String,e1: Expr,f2: String,x2: String,e2: Expr,sigma: Environment) extends Environment
/* -- We need to redefine values to accomodate the new representation of environments --*/
case class NumValue(d: Double) extends Value
case class BoolValue(b: Boolean) extends Value
case class Closure(x: String,pi: Environment) extends Value
case object ErrorValue extends Value
/*2. Operators on values */
def valueToNumber(v: Value): Double = v match {
case NumValue(d) => d
case _ => throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a number")
}
def valueToBoolean(v: Value): Boolean = v match {
case BoolValue(b) => b
case _ => throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a boolean")
}
def valueToClosure(v: Value): Closure = v match {
case Closure(x,e,pi) => Closure(x,pi)
case _ => throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a closure")
}
/*-- Operations on environments --*/
def lookupEnv(sigma: Environment,x: String): Value = sigma match {
case EmptyEnv => throw new IllegalArgumentException(s"Error could not find string $x in environment")
case Extend(y,v,_) if y == x => v
case Extend(_,_,pi) => lookupEnv(pi,x)
case ExtendRec(f,y,pi) => if (x == f)
Closure(y,sigma)
else
lookupEnv(pi,x)
case ExtendMutualRec2(f1,x1,e1,f2,x2,e2,pi ) =>
{
if (x == f1)
Closure(x1,sigma)
else if (x == f2)
Closure(x2,sigma)
else
lookupEnv(pi,x)
}
}
case class Seq(e1: Expr,e2: Expr) extends Expr
....
....
case Seq(e1,e2) => {
val (v1,store1) = evalExpr(e1,env,store)
val (v2,store2) = evalExpr(e2,store1)
(v2,store2)
}
解决方法
关于规则1,看来您应该再向评估人员添加一个案例
def evalExpr(e: Expr,env: Environment,store: ???): (Value,???) = e match {
//...
case Seq(e1,e2) =>
val (v1,store1) = evalExpr(e1,env,store)
val (v2,store2) = evalExpr(e2,store1) // what if v1 = error?
(v2,store2)
case LetRec2(f1,x1,e1,f2,x2,e2,env) =>
evalExpr(e,ExtendMutualRec2(f1,env),store /*???*/)
}