简体   繁体   English

上下文边界的语法较短?

[英]Shorter syntax for context bounds?

Is there a way to use shorter syntax when using context-bound type parameters? 使用上下文绑定类型参数时,是否可以使用较短的语法? At the moment I have something like this 此刻我有这样的事情

case class Vector2D[a : Numeric](x: a, y: a) {
  val numA = implicitly[Numeric[a]]

  def length2 = numA.plus(numA.times(x, x), numA.times(y, y))
}

and it makes more complex formulae unreadable. 这使得更复杂的公式变得不可读。

Try this REPL session: 试试这个REPL会话:

scala>  case class Vector2D[T : Numeric](x: T, y: T) {
  val numeric = implicitly[Numeric[T]]
  import numeric._
  def length2 = (x*x)+(y*y)
}

defined class Vector2D

scala> Vector2D(3,4).length2
res0: Int = 25

This is because Numeric contains an implicit conversion called mkNumericOps which you can import as shown above. 这是因为Numeric包含一个称为mkNumericOps的隐式转换,您可以如上所述导入。 If it didn't come out of the box, the way you could roll this yourself would be something like: 如果它不是开箱即用的,那么您可以自己滚动它的方式将是:

scala> implicit class NumericOps[T](val x: T) extends AnyVal { def +(y: T)(implicit n: Numeric[T]): T = n.plus(x, y)
     | def *(y: T)(implicit n: Numeric[T]): T = n.times(x, y)
     | }
defined class NumericOps

scala> case class Vector2D[a : Numeric](x: a, y: a) { def length2 = (x*x)+(y*y) }
defined class Vector2D

scala> Vector2D(3,4).length2
res0: Int = 25

If you make NumericOps not a value class (don't extend AnyVal) then the implicit Numeric can go on the constructor instead of each method, which might be better, or not really matter. 如果您使NumericOps不是值类(不扩展AnyVal),则隐式Numeric可以继续使用构造方法而不是每种方法,这可能更好,也可能无关紧要。

Anyway there's no need to write your own since Numeric already has mkNumericOps . 无论如何,由于Numeric已经具有mkNumericOps因此无需编写自己的mkNumericOps

These "ops" classes are called the "enrich my library" pattern. 这些“操作”类称为“丰富我的库”模式。

Numeric.Ops is here and the implicit being imported to auto-create it is mkNumericOps on Numeric, here . Numeric.Ops这里 ,导入的用于自动创建的隐式是mkNumericOps上的mkNumericOps在这里

Just 只是

import Numeric.Implicits._

then for every type that for which an implicit Numeric can be found 那么对于每个可以找到隐式数值的类型

(importing just the NumericOps conversion of one Numeric instance as suggested by @Havoc P gives you finer control as to for which types operations are available, but most of the time, Numeric.Implicits should be fine) (仅导入@Havoc P建议的一个Numeric实例的NumericOps转换可让您更好地控制哪些类型的操作可用,但在大多数情况下, Numeric.Implicits应该很好)

On the more general question is there a shorter syntax when using context bounds type parameters: in general, there is not. 在更一般的问题上,使用上下文边界类型参数时语法是否较短:通常没有。 It is up to the typeclass to provide some sugar to make it easy to use, as Numeric does here. 正如Numeric所做的那样,由类型类决定是否提供一些糖以使其易于使用。

For instance, it is more or less customary to have an apply method in the companion object which makes getting the instance a little easier than with implicitly 例如,在同伴对象中或多或少地习惯于有一个apply方法,这使得获取实例比隐式使用更加容易

object Ordering {
   def apply[T](implicit ord: Ordering[T]): Ordering[T] = implicitly[Ordering[T]]
}

so that you can get the implicit just with eg Ordering[Int] , rather than implicitly[Ordering[Int]] . 这样您就可以使用例如Ordering[Int]而不是implicitly[Ordering[Int]]来获取隐式。

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

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