Семейный полиморфизм со ScalaTest - PullRequest
1 голос
/ 16 февраля 2020

Я пытаюсь достичь чего-то с помощью ScalaTest и основываясь на C. Я думаю, это связано с «семейным полиморфизмом» Хосртманна «Scala для нетерпеливых». Очевидно, я ничего не понимаю в системе типов Scala, поэтому я терплю неудачу.

Короче говоря, это то, что я пытаюсь сделать.

I иметь базовую (производственную) черту:

trait MaxPQ[Key] {

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

  ...

  def insert(v: Key): Unit

  def max(): Key

  def delMax(): Key

  ...
}

, тогда существует ряд реализаций (использующих либо дерево поддержки, либо массив).

В тестах я хочу создать реферат структура, которая позволила бы протестировать любую реализацию в течение трех Ordered Key s: Char, Int, Double.

Сначала я написал два поведения (для пустых и непустых приоритетных очередей). Вот фрагмент:

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

Как правильно настроить тестирование? фреймворк? Пожалуйста, не стесняйтесь спрашивать подробности, разъяснения.

1 Ответ

2 голосов
/ 16 февраля 2020

С учетом

nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)

вывод типа выводит type T = Char, поскольку тип charMaxPQ равен MaxPQ[Char], поэтому

T <: Ordered[T]

становится Char <: Ordered[Char]

что, безусловно, не соответствует действительности. Возможно, попробуйте указать Ordering примерно так

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

Обратите внимание на разницу между верхняя граница T <: Ordered[T] и контекстная граница T: Ordering .

...