【发布时间】:2021-02-03 01:04:28
【问题描述】:
在这里,我根据涉及在 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, e: Expr, 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, e, 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, e, pi) => if (x == f)
Closure(y, e, sigma)
else
lookupEnv(pi, x)
case ExtendMutualRec2(f1, x1, e1, f2, x2, e2, pi ) =>
{
if (x == f1)
Closure(x1, e1, sigma)
else if (x == f2)
Closure(x2, e2, 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, env, store1)
(v2, store2)
}
【问题讨论】:
-
您的问题缺少上下文。可能在相互递归之前,您正在实现普通递归和非递归
let。 -
@DmytroMitin 提前致歉。我不想过多地考虑我所缺少的内容是显而易见的。那是正确的。让我们以前
-
您没有提供
Expr层次结构。evalExpr的签名是什么?你可以尝试用你的语言编写一个相互递归的测试程序(例如isOdd: Num -> Bool、isEven: Num -> Bool),看看它是否被正确评估。 -
第一张截图
eval有两个参数(表达式和环境),第二张截图有三个参数。 -
您找到问题的答案了吗?
标签: scala pattern-matching semantics