ScalaTest 的家族多态性
Family polymorphism with ScalaTest
我正在尝试使用 ScalaTest 实现一些基于 C. Hosrtmann 的“Scala for the impatient”我认为这与“家族多态性”有关。显然我不了解 Scala 的类型系统,所以我失败了。
长话短说,这就是我想要做的。
我有一个基本(生产)特征:
trait MaxPQ[Key] {
implicit protected val cmp: Ordering[_ >: Key]
...
def insert(v: Key): Unit
def max(): Key
def delMax(): Key
...
}
然后有许多实现(使用支持树或数组)。
在测试中,我想创建一个抽象结构,允许测试三个 Ordered
Key
的任何实现:Char
、Int
、Double
.
首先我写了two behaviors(针对空和非空优先级队列)。这是一个片段:
trait MaxPQBehaviours {
// underlying tests spec
self: BaseSpec =>
def nonEmptyMaxPQ[T <: Ordered[T], ImplLà <: MaxPQ[T]](instanceSupplier: () => ImplLà, sortedInput: List[T]): Unit = {
...
behavior of "size"
it should s"be equal to ${sortedInput.size}" in {
val instance = instanceSupplier()
instance.size() shouldEqual sortedInput.size
}
behavior of "max"
it should s"return the expected $max" in {
val instance = instanceSupplier()
instance.max() shouldEqual max
}
...
最后,为了添加最后一层抽象,我添加了一个 BaseMaxPQSpec
,它混合了上面的 MaxPQBehaviours
并调用了三种抽象 MaxPQ
类型的行为。这里我只提供 Char
:
trait BaseMaxPQSpec extends BaseSpec with MaxPQBehaviours {
type CharMaXPQ <: MaxPQ[Char]
def charMaxPQ: CharMaXPQ
val sortedCharsList: List[Char] = List[Char]('C', 'b', 'd', 'a', 'z').sorted
it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
}
这就是编译器向我吐槽的地方:
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:25: inferred type arguments [Char,BaseMaxPQSpec.this.CharMaXPQ] do not conform to method nonEmptyMaxPQ's type parameter bounds [T <: Ordered[T],ImplLà <: ca.vgorcinschi.algorithms2_4.MaxPQ[T]]
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:42: type mismatch;
[error] found : () => BaseMaxPQSpec.this.CharMaXPQ
[error] required: () => ImplLà
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:56: type mismatch;
[error] found : List[Char]
[error] required: List[T]
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] three errors found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 12 s, completed Feb 15, 2020 6:21:35 PM
设置测试框架的正确方法是什么?请不要犹豫,询问详情和说明。
给定
nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
类型推断推导出type T = Char
因为charMaxPQ
的类型是MaxPQ[Char]
,因此
T <: Ordered[T]
变成Char <: Ordered[Char]
这肯定不是真的。也许尝试像这样指定
def nonEmptyMaxPQ[T: Ordering, Impl <: MaxPQ[T]](instanceSupplier: () => Impl, sortedInput: List[T])
注意上限T <: Ordered[T]
和上下文绑定T: Ordering
.