【问题标题】:Why are these scalacheck recursive generators not equivalent?为什么这些 scalacheck 递归生成器不等效?
【发布时间】:2014-02-08 19:34:23
【问题描述】:

在尝试学习 ScalaCheck 工具时,我编写了两个版本的地图生成器(我知道其中有一个内置的,但这是一个练习)。

看起来genMap0genMap00应该是等价的,genMap00更干净一些,但实际上genMap0有效,但genMap00惨败。

yield 装饰有println,可以打开它以查看发生了什么(只需编辑speak 方法),但即使有了这些信息,我也不能说我真的明白为什么会有差异。这让我觉得我尝试编写的另一个生成器也可能有缺陷。

有人可以很好地解释genMap0genMap00 之间的区别吗?

  import org.scalacheck._
  import Arbitrary._
  import Gen._
  import Prop._

  def speak(message: String): Unit = if (false) println(message)

  lazy val genMap0: Gen[Map[Int, Int]] = for {
    k <- arbitrary[Int]
    v <- arbitrary[Int]
    b <- arbitrary[Boolean]
    m <- if (b) value(Map.empty[Int, Int]) else genMap0
  } yield if (b) {
    speak("false"); m
  } else {
    speak("true"); m.updated(k, v)
  }

  lazy val genMap00: Gen[Map[Int, Int]] = for {
    k <- arbitrary[Int]
    v <- arbitrary[Int]
    m <- oneOf(Map.empty[Int, Int], genMap00)
  } yield if (m.isEmpty) {
    speak("empty:" + m); m
  } else {
    speak("not empty:" + m); m.updated(k, v)
  }

  val n = 5
  for (i <- 1 to n; m <- genMap0.sample) println(m)
  println("--------------")
  for (i <- 1 to n; m <- genMap00.sample) println(m)

这是输出(genMap00 总是生成空地图):

scala -cp scalacheck_2.10-1.10.1.jar
...
// Exiting paste mode, now interpreting.

Map()
Map(1 -> 1, 1530546613 -> -1889740266, -187647534 -> 0)
Map()
Map(-1 -> 2039603804)
Map(646468221 -> 1)
--------------
Map()
Map()
Map()
Map()
Map()

【问题讨论】:

    标签: scala scalacheck


    【解决方案1】:

    递归生成的问题总是以空映射开始,因此gen00 总是以生成空映射的生成器结束。问题是空条件也被用于检测终止。

    这是由gen000修复的:

      lazy val genMap000: Gen[Map[Int, Int]] = for {
        k <- arbitrary[Int]
        v <- arbitrary[Int]
        m <- oneOf(None, genMap000.map(g => Some(g)))
      } yield (for (x <- m) yield x.updated(k, v)).getOrElse(Map())
    

    这使用中间Option[Map]None 状态表示终止。

    使用显式 Boolean 生成器似乎更简洁。

    【讨论】:

      猜你喜欢
      • 2013-11-18
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2015-03-11
      • 2012-08-02
      • 1970-01-01
      相关资源
      最近更新 更多