简体   繁体   中英

Context bounds and pattern matching in scala

I am experimenting with context bounds in scala and I don't find a way to make the either of these two functions 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
}

In the case of addExp1, I can understand that the compiler has no information at the function definition point to know that the arguments of Val are Numeric and thus have a + method. It just matches Any as the type of v1.

In the case of addExp2, how can I force the bound in the pattern? The type is "erased"...T annotation is eliminated by erasure...

What I would dream of having is a single point to put the bound, ideally at the definition of the Val class.

One way to avoid losing the parameterised type of Val is to have Expr take a type parameter as well.

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)

This compiles with no warnings.

Now all we need is a way to specify a default type of Nothing for the type parameter of Expr :).

The problem is that when you pattern match, the two instances of Val can have different type parameters, say Val[T1] and Val[T2] .

You can fix that as suggested by @rjsvaljean, and add import Numeric.Implicits._ to use the nice operator notation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM