推荐的方法来迭代没有任何共同点的类型类型的集合?

时间:2016-01-19 02:13:14

标签: scala typeclass

我正在学习Atomic Sc​​ala中的类型类。我理解类型类的目的(因为你拥有专用于功能的继承关系,而不是将它们放在类型本身上,这使得你可以拥有可扩展的系统),但这本书提出了一个有趣的问题。

在传统的多态中,您的类型受继承层次结构的约束。因此,如果你有一个Shape和Circle,Triangle等扩展形状,那么Shapes的Vector就像Vector(Circle, Triangle, ...)一样有效。

但是,使用类型类模式时类型之间没有关系。所以矢量(圆形,三角形)只是Serializable的矢量。我设法使用类型类方法(areaForShape)的方法是使用模式匹配来向下钻取并解析特定类型,以便类型类方法可以推断出正确的类型,并且可以注入正确的类型类实现。

有没有更好的方法来处理这种迭代?

import scala.math.{sqrt, Pi}

// type-class functionality we want to have applied
// to existing types without touching their internals
trait Calc[S] {
  def area(shape: S): Double
}
// type-class method
def areaForShape[S](shape: S)(implicit calc: Calc[S]) =
  calc.area(shape)

// specific CircleCalc implementation of the type-class
// injected into environment that implements area of a Circle
implicit object CircleCalc extends Calc[Circle] {
  override def area(shape: Circle): Double = 2 * Pi * shape.radius
}

// specific EQLTriangleCalc implementation of the type-class
// injected into environment that implements area of an EQLTriangle
implicit object EQLTriangleCalc extends Calc[EQLTriangle] {
  override def area(shape: EQLTriangle): Double = (sqrt(3)/4) * shape.side * shape.side
}

case class Circle(radius: Double)
case class EQLTriangle(side: Double)

Vector(Circle(1), EQLTriangle(3)).map{
  case c: Circle => areaForShape(c)
  case t: EQLTriangle => areaForShape(t)
}

0 个答案:

没有答案