【问题标题】:Family polymorphism with ScalaTestScalaTest 的族多态性
【发布时间】:2020-05-31 07:14:27
【问题描述】:

我正在尝试使用 ScalaTest 实现一些目标,并基于 C. Hosrtmann 的“不耐烦的 Scala”,我认为这与“家庭多态性”有关。显然我不了解 Scala 的类型系统,所以我失败了。

长话短说,这就是我想要做的。

我有一个基本(生产)特征:

trait MaxPQ[Key] {

  implicit protected val cmp: Ordering[_ >: Key]
  
  ...

  def insert(v: Key): Unit

  def max(): Key

  def delMax(): Key

  ...
}

然后有许多实现(使用支持树或数组)。

在测试中,我想创建一个抽象结构,允许测试三个Ordered Keys 的任何实现:CharIntDouble

首先我写了two behaviors(用于空和非空优先级队列)。这是一个sn-p:

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

设置我的测试框架的正确方法是什么?请不要犹豫,询问详细信息和说明。

【问题讨论】:

    标签: scala scalatest


    【解决方案1】:

    给定

    nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
    

    类型推断推导出type T = Char,因为charMaxPQ的类型是MaxPQ[Char],因此

    T <: Ordered[T]
    

    变成Char &lt;: Ordered[Char]

    这当然不是真的。也许尝试像这样指定Ordering

    def nonEmptyMaxPQ[T: Ordering, Impl <: MaxPQ[T]](instanceSupplier: () => Impl, sortedInput: List[T])
    

    注意上限T &lt;: Ordered[T]上下文限制T: Ordering之间的区别。

    【讨论】:

    • 非常感谢马里奥!那行得通!我尝试以与在 Java 中使用 T extends Comparable&lt;T&gt; 相同的方式使用 Ordered[T]。所以关于这个主题我肯定需要阅读一些内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多