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

2024-01-05

我有以下财产:

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


问题是你有一个if真实面具有类型的表达式Boolean假面有类型Prop。编译器将应用propBoolean在需要的情况下隐式转换为布尔值Prop,但像这样的条件不是这些地方之一 - 相反,编译器只是采用最小上界Boolean and Prop并将其设为返回类型。 (也许更令人惊讶的是,即使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(极其复杂)语法的其他角落交互,这些技巧就会崩溃。 。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ScalaCheck 无法将布尔值转换为 Prop 实例 的相关文章