gpt4 book ai didi

Scala 自定义不适用泛型

转载 作者:行者123 更新时间:2023-12-02 03:36:40 24 4
gpt4 key购买 nike

我想通过自定义通用的 unapply 函数来压缩我的求值器,它会计算参数并在成功时返回值。

但这失败并出现错误 error: not found: type Eval

有什么方法可以实现吗?我看过typetags , implicit conversions for unapply methods但我不知道如何将它们整合到这个问题中。如何正确定义Eval?

object Test {
case class Context()

trait Expr
trait Literal[T] extends Expr{
def value : T
}
case class IntLiteral(value: Int) extends Literal[Int]
case class StringLiteral(value: Int) extends Literal[Int]
case class Plus(e: Expr, f: Expr) extends Expr

object Eval { // Here I want the magic unapply to evaluate the expression.
def unapply[T](e: Expr)(implicit gctx: Context): Option[T] = {
eval(e) match {
case e: Literal[T] => Some(e.value)
case _ => None
}
}
}

def eval(e: Expr)(implicit c: Context): Expr = e match {
case Plus(Eval[Int](i), Eval[Int](j)) => IntLiteral(i+j) // Fails here.
case IntLiteral(i) => e
case StringLiteral(s) => e
}

eval(Plus(Plus(IntLiteral(1),IntLiteral(2)),IntLiteral(3)))(Context())
}

最佳答案

Eval[Int](...) 根本不是合法的模式,因此您无法获得此语法。您可以使 Eval 本身成为通用的,并为您想要的类型创建实例:

object Test {
case class Context()

trait Expr
trait Literal[T] extends Expr {
def value: T
}
case class IntLiteral(value: Int) extends Literal[Int]
case class StringLiteral(value: Int) extends Literal[Int]
case class Plus(e: Expr, f: Expr) extends Expr

case class Eval[T]() {

def unapply(e: Expr)(implicit gctx: Context): Option[T] = {
eval(e) match {
case e: Literal[T] => Some(e.value)
case _ => None
}
}
}

val IntEval = Eval[Int]()

def eval(e: Expr)(implicit c: Context): Expr = e match {
case Plus(IntEval(i), IntEval(j)) => IntLiteral(i + j)

case IntLiteral(i) => e
case StringLiteral(s) => e
}

println(eval(Plus(Plus(IntLiteral(1), IntLiteral(2)), IntLiteral(3)))(Context()))
}

但请注意,这不会检查文字的类型!如果你也想要这个,你需要 ClassTag 并且这只允许匹配 : T,而不是 : Literal[T]:

object Test {
case class Context()

trait Expr
case class Literal[T](value: T) extends Expr // or case class Literal(value: Any)
case class Plus(e: Expr, f: Expr) extends Expr

case class Eval[T]()(implicit tag: scala.reflect.ClassTag[T]) {

def unapply(e: Expr)(implicit gctx: Context): Option[T] = {
eval(e) match {
case Literal(value: T) => Some(value)
case _ => None
}
}
}

val IntEval = Eval[Int]()

def eval(e: Expr)(implicit c: Context): Expr = e match {
case Plus(IntEval(i), IntEval(j)) => Literal(i + j)

case e: Literal[_] => e
}

println(eval(Plus(Plus(Literal(1), Literal(2)), Literal(3)))(Context()))
}

关于Scala 自定义不适用泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22969821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com