我正在学习Atomic Scala中的类型类。我理解类型类的目的(因为你拥有专用于功能的继承关系,而不是将它们放在类型本身上,这使得你可以拥有可扩展的系统),但这本书提出了一个有趣的问题。
在传统的多态中,您的类型受继承层次结构的约束。因此,如果你有一个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)
}