简体   繁体   English

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

[英]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: 我正在使用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
}

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. 在addExp1的情况下,我可以理解编译器在函数定义点没有信息知道Val的参数是Numeric,因此有一个+方法。 It just matches Any as the type of v1. 它只匹配Any作为v1的类型。

In the case of addExp2, how can I force the bound in the pattern? 在addExp2的情况下,如何强制模式中的绑定? The type is "erased"...T annotation is eliminated by erasure... 类型被“擦除”......删除时删除了T注释...

What I would dream of having is a single point to put the bound, ideally at the definition of the Val class. 我梦想拥有的是一个单一的点来放置界限,理想情况下是Val类的定义。

One way to avoid losing the parameterised type of Val is to have Expr take a type parameter as well. 避免丢失参数化类型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)

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 :). 现在我们需要的是为Expr :)的类型参数指定默认类型Nothing的方法。

The problem is that when you pattern match, the two instances of Val can have different type parameters, say Val[T1] and Val[T2] . 问题是当你模式匹配时, Val的两个实例可以有不同的类型参数,比如Val[T1]Val[T2]

You can fix that as suggested by @rjsvaljean, and add import Numeric.Implicits._ to use the nice operator notation. 您可以按照@rjsvaljean的建议修复它,并添加import Numeric.Implicits._以使用nice运算符表示法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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