我如何专门化具有 None-type 约束的特征?
How can I specialize a trait with a None-type constraint?
首先,如果我的问题不清楚,请允许我道歉。我还没有完全掌握 Scala 的用语,所以我可能会混淆术语。不过,我认为我的例子会更清楚。
我正在尝试创建一个特征 Hierarchical
,它基本上描述了图中的顶点——任何 object 都可以有一个列表 parents 和一个列表 children.
更具体地说:
1) A Hierarchical
可能有也可能没有 parents.
2) 如果是,则 parents 是 Hierarchical
。
3) 一个Hierarchical
会有children,也就是Hierarchical
.
这是我的一般特征:
/*
Hierarchical takes two type parameters: Parent and Child.
These should be Hierarchicals with parameters Parent and Child as well.
*/
trait Hierarchical[Parent <: Hierarchical[Parent, Child],
Child <: Hierarchical[Parent, Child]] {
// parents must be passed by constructor lest they are treated as None.
// (Requirement 1, 2)
val parents: Option[List[Hierarchical[Parent, Child]]] = None
// children can be added, so mutability needed (Requirement 3)
var children: List[Hierarchical[Parent, Child]] = List()
def addChild(child: Child) = children ++= List(child)
}
对此的特化是 "root" 顶点,其 parents 将不存在,因此根本不应指定类型 - 因此,它是 None
。这是我尝试专门化 Hierarchical
特征:
/*
A RootHierarchical has no parents. It does, however, have
children whose parents are RootHierarchicals and whose children
are Child.
A parent can be none (Requirement 1)
*/
trait RootHierarchical[Child <: Hierarchical[RootHierarchical, Child]]
extends Hierarchical[None.type, Child] {
override val parents = None
}
IntelliJ 对此很满意,但我写的测试无法编译:
import org.scalatest.FlatSpec
class TestHierarchy extends FlatSpec {
"A Hierarchical object" should "be constructable" in {
/*
Create a dummy
*/
class DummyHierarchical(override val parents: List[DummyParentHierarchical])
extends Hierarchical[DummyParentHierarchical, DummyHierarchical]
class DummyParentHierarchical extends RootHierarchical[DummyHierarchical]
val dummyParent = new DummyParentHierarchical
val dummyChild = new DummyHierarchical(List(dummyParent))
dummyParent.addChild(dummyChild)
assert(dummyParent.parents.isEmpty)
assert(dummyParent.children.nonEmpty)
}
}
错误在这里:
Error:(14, 11) type arguments [None.type,Child] do not conform to trait Hierarchical's type parameter bounds [Parent <: Hierarchical[Parent,Child],Child <: Hierarchical[Parent,Child]]
extends Hierarchical[None.type, Child] {
我的问题是:如何创建此专业?我知道 None.type
不是 Hierarchical
类型,但我如何专门研究它?
经过一些头脑风暴后,我发现 parents 的类型不需要指定——它们可以是某种任意的层次类型,并且会有一个默认值 Nil
。
这是我的实现:
// T is the type of children -- they should be Hierarchicals.
trait Hierarchical[T <: Hierarchical[T]] {
// The parents will be a list of some arbitrary Hierarchical
val parents: List[Hierarchical[_]] = Nil
var children: List[Hierarchical[T]] = List()
}
// Nodes that aren't root nodes will have parents specified by ctor
class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {}
// Roots will have no way to update their parents.
class Root extends Hierarchical[NonRootNode] {
final override val parents = Nil
}
这是一个带有一些测试的小驱动程序:Ideone it
首先,如果我的问题不清楚,请允许我道歉。我还没有完全掌握 Scala 的用语,所以我可能会混淆术语。不过,我认为我的例子会更清楚。
我正在尝试创建一个特征 Hierarchical
,它基本上描述了图中的顶点——任何 object 都可以有一个列表 parents 和一个列表 children.
更具体地说:
1) A
Hierarchical
可能有也可能没有 parents.2) 如果是,则 parents 是
Hierarchical
。3) 一个
Hierarchical
会有children,也就是Hierarchical
.
这是我的一般特征:
/*
Hierarchical takes two type parameters: Parent and Child.
These should be Hierarchicals with parameters Parent and Child as well.
*/
trait Hierarchical[Parent <: Hierarchical[Parent, Child],
Child <: Hierarchical[Parent, Child]] {
// parents must be passed by constructor lest they are treated as None.
// (Requirement 1, 2)
val parents: Option[List[Hierarchical[Parent, Child]]] = None
// children can be added, so mutability needed (Requirement 3)
var children: List[Hierarchical[Parent, Child]] = List()
def addChild(child: Child) = children ++= List(child)
}
对此的特化是 "root" 顶点,其 parents 将不存在,因此根本不应指定类型 - 因此,它是 None
。这是我尝试专门化 Hierarchical
特征:
/*
A RootHierarchical has no parents. It does, however, have
children whose parents are RootHierarchicals and whose children
are Child.
A parent can be none (Requirement 1)
*/
trait RootHierarchical[Child <: Hierarchical[RootHierarchical, Child]]
extends Hierarchical[None.type, Child] {
override val parents = None
}
IntelliJ 对此很满意,但我写的测试无法编译:
import org.scalatest.FlatSpec
class TestHierarchy extends FlatSpec {
"A Hierarchical object" should "be constructable" in {
/*
Create a dummy
*/
class DummyHierarchical(override val parents: List[DummyParentHierarchical])
extends Hierarchical[DummyParentHierarchical, DummyHierarchical]
class DummyParentHierarchical extends RootHierarchical[DummyHierarchical]
val dummyParent = new DummyParentHierarchical
val dummyChild = new DummyHierarchical(List(dummyParent))
dummyParent.addChild(dummyChild)
assert(dummyParent.parents.isEmpty)
assert(dummyParent.children.nonEmpty)
}
}
错误在这里:
Error:(14, 11) type arguments [None.type,Child] do not conform to trait Hierarchical's type parameter bounds [Parent <: Hierarchical[Parent,Child],Child <: Hierarchical[Parent,Child]]
extends Hierarchical[None.type, Child] {
我的问题是:如何创建此专业?我知道 None.type
不是 Hierarchical
类型,但我如何专门研究它?
经过一些头脑风暴后,我发现 parents 的类型不需要指定——它们可以是某种任意的层次类型,并且会有一个默认值 Nil
。
这是我的实现:
// T is the type of children -- they should be Hierarchicals.
trait Hierarchical[T <: Hierarchical[T]] {
// The parents will be a list of some arbitrary Hierarchical
val parents: List[Hierarchical[_]] = Nil
var children: List[Hierarchical[T]] = List()
}
// Nodes that aren't root nodes will have parents specified by ctor
class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {}
// Roots will have no way to update their parents.
class Root extends Hierarchical[NonRootNode] {
final override val parents = Nil
}
这是一个带有一些测试的小驱动程序:Ideone it