具有路径依赖类型和协变参数的 Scala 复制类



我在路径相关类型和协变参数方面遇到了一些麻烦。我需要创建一个新的 SomeFancyCollection 实例,但由于 Path 依赖类型,它无法编译。当我从类中提取所有像 Node 和 Branch 之类的东西时,我必须将根参数声明为 private[this],我也无法获得该类的新实例。 我的代码如下所示:

class SomeFancyCollection[+A] {
private var root: Node = Branch(0x0, Vector[Node]())
trait Node {
val id: Byte
def put[A1 >: A](ids: Seq[Byte], item: A1): Node
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node
}
case class Branch(id: Byte, subs: Vector[Node]) extends Node {
...
}
case class Leaf[A1 >: A](id: Byte, subs: Vector[A1]) extends Node {
...
}
def add[A1 >: A](item: A1): SomeFancyCollection[A1] = {
val ids: Seq[Byte] = getIds() // doesn't matter
val newRoot = root.put(ids, item)
val newInstance = new SomeFancyCollection[A1]()
newInstance.root = newRoot
newInstance
}
}

在您的代码中,没有明显的理由使NodeLeaf嵌套的路径相关类。只要使它们成为协变独立类,那么路径依赖的所有问题都会消失:

trait Node[+A] {
val id: Byte
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1]
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1]
}
case class Branch[+A](id: Byte, subs: Vector[Node[A]]) extends Node[A] {
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
}
case class Leaf[+A](id: Byte, subs: Vector[A]) extends Node[A] {
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
}

class SomeFancyCollection[+A](val root: Node[A] = Branch(0x0, Vector[Node[A]]())) {
def add[A1 >: A](item: A1): SomeFancyCollection[A1] = {
val ids: Seq[Byte] = ???// getIds() // doesn't matter
val newRoot = root.put(ids, item)
new SomeFancyCollection[A1](newRoot)
}
}

如果你不想污染命名空间,只需声明Node类包私有,甚至将所有辅助实现细节类隐藏在SomeFancyCollection的配套对象中:

class SomeFancyCollection[+A] private[SomeFancyCollection](
val root: SomeFancyCollection.AnnoyingDetails.Node[A]
) {
def add[A1 >: A](item: A1): SomeFancyCollection[A1] = {
val ids: Seq[Byte] = ???// getIds() // doesn't matter
val newRoot = root.put(ids, item)
new SomeFancyCollection[A1](newRoot)
}
}
object SomeFancyCollection {
def empty[A]: SomeFancyCollection[A] = new SomeFancyCollection[A](
AnnoyingDetails.Branch(0x0, Vector[AnnoyingDetails.Node[A]]())
)
private[SomeFancyCollection] object AnnoyingDetails {
trait Node[+A] {
val id: Byte
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1]
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1]
}
case class Branch[+A](id: Byte, subs: Vector[Node[A]]) extends Node[A] {
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
}
case class Leaf[+A](id: Byte, subs: Vector[A]) extends Node[A] {
def put[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
def remove[A1 >: A](ids: Seq[Byte], item: A1): Node[A1] = ???
}
}
}

相关内容

  • 没有找到相关文章

最新更新