繁体   English   中英

斯卡拉高型型总厂

[英]Scala higher-kinded types general factory

我一直在与scala一起玩耍,再次测试一些语言类型检查功能。 我正在尝试实现一个旨在用于图形的矢量库,并且我想尽可能多地使用scala类型检查器,以便在使用它时获得早期的编译时警告。 我到目前为止所得到的。

trait VecT

abstract sealed class Vec[T,V[T] <: VecT](elems: T*)(implicit num: VecIntegral[T]) extends VecT {
  import num._

  def +(v: V[T]): V[T] = ???
  def -(v: V[T]): V[T] = ???
  def cross(v: V[T]): V[T] = ???
  def dot(v: V[T]): T = ???
  def unary_-(): V[T] = ???
  def *(scalar: T): V[T] = ???
  def abs: T = ???
  def *(v: V[T]): V[T] = cross(v)
  def apply(n: Int): T = ???
}

class Vec2[T](x: T, y: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec2](x,y)
class Vec3[T](x: T, y: T, z: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec3](x,y,z)

这使我可以对操作进行编译时检查,即使+运算符在abstract类中实现也是如此

(new Vec3[Int](1,2,3)) + (new Vec3[Int](1,2,3))
(new Vec3[Int](1,2,3)) + (new Vec2[Int](1,2)) // Failes compilation

这就是我想要的。

到现在为止还挺好。 现在我想在抽象类中实现一个map函数,例如

def map[A](f: T => A): V[A] = Vec(elems.map(f):_*)

因此,我实现这一目标的尝试将是创建一个通用的Vec工厂

object Vec {
  def apply[T, V[T] <: VecT](elemes: T*)(implicit num: VecIntegral[T]): V[T] = elems match {
    case Seq(x,y)   => new V[T](x,y)
    case Seq(x,y,z) => new V[T](x,y,z)
}

但这行不通, expression of type V does not comform to exptected type V[T]

所以我的问题。 有没有像这样实现工厂的“良好”通用方法?

有关为什么new V[T](...)不起作用也不应该起作用的原因,请参见https://stackoverflow.com/a/39286308/9204 一种解决方案是

trait VecFactory[V[_]] { def newVec[T](elems: Seq[T]): V[T] }

abstract sealed class Vec[T,V[T] <: VecT](elems: T*)(implicit num: VecIntegral[T], factory: VecFactory[V]) {
  def map[A](f: T => A): V[A] = factory.newVec(elems.map(f))
}
class Vec2[T](x: T, y: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec2](x,y)
object Vec2 {
  implicit val factory: VecFactory[Vec2] = new VecFactory[Vec2] { 
    def newVec[T](elems: Seq[T]) = new Vec2(elems(0), elems(1))
  }
}

class Vec3[T](x: T, y: T, z: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec3](x,y,z)
object Vec3 {
  implicit val factory: VecFactory[Vec3] = ...
}

请注意,这仍然不是十分安全:需要使用特定长度的序列来调用工厂。

暂无
暂无

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

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