0
在試圖學習ScalaCheck工具時,我寫了兩個版本的Map生成器(我知道其中有一個內置,但這是一個練習)。這些scalacheck遞歸生成器爲什麼不等價?
似乎genMap0
和genMap00
應該是等價的,並且genMap00
是有點清潔,但實際上genMap0
作品,但genMap00
悲慘的失敗了。
的yield
裝飾着一個println
可以打開,看看有什麼發生(只需編輯speak
方法),但即使有這樣的信息,我不能說我真正明白爲什麼差異。這讓我認爲我試圖寫的另一個發電機也可能有缺陷。
有人可以給出一個很好的解釋genMap0
和genMap00
之間有什麼不同嗎?
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()