当前位置: 首页 > 知识库问答 >
问题:

Scala自定义不适用于泛型

辛承志
2023-03-14

我想通过一个自定义的泛型unapply函数压缩我的计算器,该函数计算参数并在成功时返回值。

但是这失败了,错误错误:未找到:类型Eval

有什么方法可以实现这一点吗?我已经研究了类型标签,不适用方法的隐式转换,但我不知道如何将它们集成到这个问题中。如何正确定义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())
}

共有1个答案

毋宪
2023-03-14

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,而不是:文字[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()))
}
 类似资料:
  • 我有一些自定义角色,例如: 当使用'ROLE_USER'时,“spans”中的文本可以正常显示,但当使用其他角色时,文本无法显示。然后我在自定义角色中添加'ROLE_'前缀,它又变得正常了。 我尝试删除“ROLE\uu0”前缀约束,如下所示: 它也不起作用。知道如何删除强制的“ROLE\uuux”前缀吗?

  • 我使用spring boot和spring boot starter hateoas开发了一个rest服务。我在定制ObjectMapper时遇到了一个问题。代码如下: 一个pplication.java 依赖关系: 账单java: BillController.java: 我得到的输出是: 但是我需要“账单”代替“billList”。这是因为ObjectMapper没有被定制。我是否错过了任何配

  • 我有一个Flume组件在监听Syslog流。我做了一个自定义的拦截器来修改调用,但它不起作用。我做错了什么?谢谢你,Andrea 拦截器是一个编译良好的JAR文件,位于@FLUME_HOME/bin目录中 系统将事件记录在文件中而不修改它们,这是相关的DEBUG日志:

  • 代码如下: 这是适配器,我在这里为列表做了自己的设计(< code>R.layout.zalistu),它在仿真器中工作,但在设备上它给我一个错误(应用程序意外停止),如果我使用< code>simple_list_item_1,那么它在仿真器和我的设备上都可以正常工作。 这里是R:layout.zalistu: 日志猫: 我设备上的Android版本是2.3.7,模拟器上的版本是4.0.4(AP

  • 问题内容: 我尝试使用Swift 4.1的新功能在JSON解码期间将蛇案转换为camelCase。 这是示例: 我需要提供习惯,因为该策略无法推断首字母缩略词或首字母缩写(例如)的大小写,但我希望该策略仍然适用。但是,解码器会引发错误(“与键CodingKeys无关的值”),看来我不能同时使用策略和自定义。我想念什么吗? 问题答案: (和)的密钥策略适用于有效负载中的所有密钥,包括您为其提供自定义

  • 您可以从http://jsbin.com/husamupi/1/edit试用代码