首页 文章

scala中的上下文边界和模式匹配

提问于
浏览
3

我正在使用scala中的上下文边界进行实验,但我找不到一种方法来使这两个函数中的任何一个成为typecheck:

abstract class Expr
case class Val[T: Numeric](v: T) extends Expr
case object Other extends Expr

val e1 = Val(1)
val e2 = Val(2)

def addExp1(e1: Expr, e2: Expr): Expr = (e1, e2) match {
  case (Val(v1), Val(v2)) => Val(v1+v2)
  case _ => Other
}

def addExp2[T: Numeric](e1: Expr, e2: Expr): Expr = (e1, e2) match {
  case (Val(v1: T), Val(v2: T)) => Val(v1+v2)
  case _ => Other
}

对于addExp1,我可以理解编译器在函数定义点没有信息知道Val的参数是Numeric,因此有一个方法 . 它只匹配Any作为v1的类型 .

在addExp2的情况下,如何强制模式中的绑定?类型被“擦除”......删除时删除了T注释...

我梦想拥有的是一个单一的点来放置界限,理想情况下是Val类的定义 .

2 回答

  • 3

    问题是当模式匹配时, Val 的两个实例可以有不同的类型参数,比如 Val[T1]Val[T2] .

    您可以按照@rjsvaljean的建议修复它,并添加 import Numeric.Implicits._ 以使用nice运算符表示法 .

  • 3

    避免丢失参数化类型Val的一种方法是让Expr也采用类型参数 .

    abstract class Expr[T]
    case class Val[T: Numeric](v: T) extends Expr[T]
    case object Other extends Expr[Nothing]
    
    val e1 = Val(1)
    val e2 = Val(2)
    
    
    
    def addExp2[T: Numeric](e1: Expr[T], e2: Expr[T]): Expr[_ <: T] = (e1, e2) match {
      case (Val(v1), Val(v2)) => Val(implicitly[Numeric[T]].plus(v1, v2))
      case _ => Other
    }
    
    
    addExp2[Int](e1, e2)
    

    编译时没有任何警告 .

    现在我们需要的是为Expr :)的类型参数指定默认类型 Nothing 的方法 .

相关问题