【发布时间】:2021-01-30 07:19:29
【问题描述】:
如何声明一个空/无大小写模式匹配函数以满足类型定义?我很高兴该函数在被调用时会抛出运行时异常。
我正在处理Scala tutorial for Java programmers,其中我有一个工作函数,它在给定String => Int 映射的情况下对呈现为树的数学表达式执行变量替换。即使不应该存在变量(在这种情况下,在对表达式求导之后),我也想调用相同的代码路径,但是我找不到满足类型要求的简洁方法。这是我拥有的完整代码,但感觉不对:
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
object CalculatorPatternsPrime {
def eval(tree: Tree, env: String => Int): Int = tree match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
def eval(tree: Tree): Int = eval(tree, { case "ignore" => -1 })
def derive(tree: Tree, v: String): Tree = tree match {
case Sum(l, r) => Sum(derive(l, v), derive(r, v))
case Var(n) if (n == v) => Const(1)
case _ => Const(0)
}
def main(args: Array[String]): Unit = {
val env: String => Int = { case "x" => 5 case "y" => 7 }
val tree = Sum(
Sum(Const(7), Var("y")),
Sum(Var("x"), Var("x"))
)
println(eval(tree, env))
println(derive(tree, "x"))
println(eval(derive(tree, "x")))
}
}
如您所见,我有一个虚拟的{ case "ignore" => -1 } 来使类型系统满意,并且代码工作正常,但我觉得必须有更好的方法来做到这一点。以下是我考虑过的两种选择:
- 只需将完整的方法主体写入
eval(tree: Tree),而不是尝试调用eval(tree: Tree, env: String => Int),但这会重复处理Sum和Const情况的代码。 - 使
env成为可选/联合类型并让它抛出 NPE。
这里的惯用方法是什么?
【问题讨论】:
-
我会删除第二个
eval()并给env提供_ => -1的默认值。
标签: scala