#1: 别担心
Arbitrary
v
Gen
。它们基本相同。这里有一个很好的答案来解释它们之间的区别:
Why do you need Arbitraries in scalacheck?
#2你正在混合你的monadic容器(
消息
和
Array
)scala正在尽最大努力将它们结合起来,这给你带来了一个令人困惑的错误。
要修复类型错误,请执行以下操作
def matrix2[ T : ClassTag]( g: Gen[ T ] )( order: Int ): Gen[ Array[ Array[ T ] ] ] =
for {
rowSeq <- Gen.listOfN( order, g )
rowArray = rowSeq.toArray
seqOfRowArrays <- Gen.listOfN( order, rowArray)
} yield seqOfRowArrays.toArray
如果你在终端中运行这个,你会注意到一些奇怪的事情:
scala> matrix2(Gen.choose(1,10))(3)
res2: org.scalacheck.Gen[Array[Array[Int]]] = org.scalacheck.Gen$$anon$6@4c93778e
scala> res2.sample
res3: Option[Array[Array[Int]]] = Some([[I@1dd38904)
scala> res3.foreach{a2 => a2.foreach{a => a.foreach{i => println(s" $i")}; println("\n")}}
6
10
5
6
10
5
6
10
5
这只生成一行,然后在整个矩阵中重复同一行。对此,我的解决方案是使用scalacleck生成^2个元素,然后将它们分组到2D数组结构中。这里是我的Scala REPL的复制/粘贴:
scala> :paste
// Entering paste mode (ctrl-D to finish)
def matrix2[T: ClassTag](g: Gen[T])(order: Int): Gen[Array[Array[T]]] =
Gen.listOfN(order*order, g).map { squareList =>
squareList.toArray.grouped(order).toArray
}
// Exiting paste mode, now interpreting.
matrix2: [T](g: org.scalacheck.Gen[T])(order: Int)(implicit evidence$1: scala.reflect.ClassTag[T])org.scalacheck.Gen[Array[Array[T]]]
scala> matrix2(Gen.choose(1,10))(3)
res5: org.scalacheck.Gen[Array[Array[Int]]] = org.scalacheck.Gen$$anon$6@7519bc73
scala> res5.sample.foreach{a2 => a2.foreach{a => a.foreach{i => println(s" $i")}; println("\n")}}
1
9
9
7
6
10
10
2
6
#3、
order
将不会更改此生成器,因为您正在使用
listOfN
方法来固定集合的大小。用户指南中的示例仅调整大小,因为它使用
Gen.sized
发电机