ScalaCheck无法将布尔值转换为Prop实例

时间:2017-02-25 13:28:57

标签: scala unit-testing scalacheck

我有以下属性:

import org.scalacheck.Prop.propBoolean

def elementsAreReversed(list: List[Int], reversed: List[Int]): Boolean =
  if (list.isEmpty) true else {
    val lastIdx = list.size - 1
    list.zipWithIndex.forall { case (element, index) =>
      element == reversed(lastIdx - index)
    }
  }

val propReversed = Prop.forAll { list: List[Int] =>
  val reversed = list.reverse

  if (list.isEmpty)
    list == reversed
  else {
    val hasSameSize    = reversed.size == list.size
    val hasAllElements = list.forall(reversed.contains)

    // It works until  I add a label here:
    hasSameSize && hasAllElements && elementsAreReversed(list, reversed)
  }

如果添加标签,则会破坏:

    hasSameSize :| " a label which doesn't let the code compile" &&
    hasAllElements &&
    elementsAreReversed(list, reversed)

编译器给出了以下内容:

错误:(47,36)Any =>中没有可用的隐式视图org.scalacheck.P​​rop。 val propReversed = Prop.forAll {list:List [Int] =>

错误:(47,36)没有足够的方法forAll:

(隐式p:Any => org.scalacheck.P​​rop,隐式a1:org.scalacheck.Arbitrary [List [Int]],隐式s1:org.scalacheck.Shrink [List [Int]],隐式pp1: List [Int] => org.scalacheck.util.Pretty)org.scalacheck.P​​rop。未指定的值参数 p,a1,s1 ......

val propReversed = Prop.forAll {list:List [Int] =>

我正在使用ScalaCheck版本1.13.4

1 个答案:

答案 0 :(得分:5)

问题是您有一个if表达式,其中true侧的类型为Boolean,而false侧的类型为Prop。在需要propBoolean的情况下,编译器会将Prop隐式转换应用于布尔值,但像这样的条件不是其中一个位置 - 而编译器只需要最少BooleanProp的上限,并使其成为返回类型。 (也许更令人惊讶的是,即使Prop排在第一位且Boolean秒,也是如此。)

有几种方法可以使这项工作,但最简单的方法是明确应用转换:

val propReversed = Prop.forAll { list: List[Int] =>
  val reversed = list.reverse

  if (list.isEmpty) Prop.propBoolean(list == reversed) else {
    val hasSameSize    = reversed.size == list.size
    val hasAllElements = list.forall(reversed.contains)

    hasSameSize :| " a label which doesn't let the code compile" &&
      hasAllElements && elementsAreReversed(list, reversed)
  }
}

对我而言,这只是花哨的隐式转换支持DSL的挫败感的另一个例子。我喜欢ScalaCheck并且每天都使用它,但是当我们开始与Scala的其他角落进行交互时,我不会真正看到后空翻的价值来支持稍微更简洁的使用。 s(非常复杂)的语法。