2012-10-18 20 views
0

我正在使用scalacheck,现在正处于通用编程中。官方指南示出此示例:为scalacheck函数获取2个implicits

def matrix[T](g: Gen[T]): Gen[Seq[Seq[T]]] = Gen.sized { size => 
    val side = scala.math.sqrt(size).asInstanceOf[Int] 
    Gen.listOfN(side, Gen.listOfN(side, g)) 
} 

同时,用于我的测试我需要类型数组[数组[T]]的矩阵。我试着用以下功能:

def matrix[T](g: Gen[T]): Gen[Array[Array[T]]] = Gen.sized { size => 
    val side = scala.math.sqrt(size).asInstanceOf[Int] 
    val g1 = Gen.containerOfN[Array, T](side, g) 
    Gen.containerOfN[Array, Array[T]](side, g1) 
} 

在这里,我遇到了麻烦。编译器表示:

多个标记在这条线 - 不够论据方法containerOfN:(隐式B:org.scalacheck.util.Buildable [T,阵列])org.scalacheck.Gen [阵列[T ]。 未指定的值参数b。 - 无法找到参数b的隐式值:org.scalacheck.util.Buildable [T,Array] - 找不到参数b的隐式值:org.scalacheck.util.Buildable [T,Array] - 不够方法containerOfN的参数:(隐式b:org.scalacheck.util.Buildable [T,Array])org.scalacheck.Gen [Array [T]]。 未指定的值参数b。

我明白这样的东西通常可以通过向函数添加隐式参数来弥补,但是,我还没有完成这项工作。

我通常建立在通用的阵列,作为一个例子会遇到这样的错误:

def build[T](n:Int)(implicit m:ClassManifest[T]) = Array.ofDim[T](n) 

,但是,我怕我不完全明白发生了什么,或者为什么这是必要的。

有人能解释如何做出正确的矩阵功能在scalacheck使用的例如,沿着?对于使用隐式类清单构建序列的详细信息的详细解释将非常受欢迎!

编辑

import org.scalacheck.util.Buildable._ 
    def matrix[T](g: Gen[T])(implicit b: Buildable[T, Array]): Gen[Array[Array[T]]] = Gen.sized { size => 

    val side = scala.math.sqrt(size).asInstanceOf[Int] 
    val g1 = Gen.containerOfN[Array, T](side, g) 
    Gen.containerOfN[Array, Array[T]](side, g1) 
    } 

还不行。需要隐式为Buildable [Array [T],Array] ...不知道如何得到这个,因为我只能添加1个隐式参数:/

回答

2

你快到了。错误的重要组成部分,是could not find implicit value for parameter b: org.scalacheck.util.Buildable[T,Array]

综观containerOfN

def containerOfN[C[_],T](n: Int, g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] = ... 

因此,有你缺少的参数的方法定义。您需要一个类型Buildable[T,Array]的隐式参数。下面我们通过在scalacheck源文件中定义Buildable,发现存在一个对象(org.scalacheck.util.Buildable),它提供暗示,为包含Array的常见集合类型提供Buildable。所以,你需要将这些纳入范围。

import org.scalacheck.util.Buildable._ 
    def matrix[T](g: Gen[T]): Gen[Array[Array[T]]] = Gen.sized { size => 
    val bT = implicitly[Buildable[T, Array]] 
    val bArrayT = implicitly[Buildable[Array[T], Array]] 

    val side = scala.math.sqrt(size).asInstanceOf[Int] 
    val g1 = Gen.containerOfN[Array, T](side, g) 
    Gen.containerOfN[Array, Array[T]](side, g1) 
    } 

或者

import org.scalacheck.util.Buildable._ 
    def matrix[T](g: Gen[T])(implicit bT: Buildable[T, Array], bArrayT: Buildable[Array[T], Array]): Gen[Array[Array[T]]] = Gen.sized { size => 
    ... 
    } 

org.scalacheck.util.Buildable需要的特定隐是:你可以做到这一点

implicit def buildableArray[T](implicit cm: ClassManifest[T]) = 
    new Buildable[T,Array] { 
    def builder = mutable.ArrayBuilder.make[T] 
    } 
+0

其实,这是行不通的。我试图将它导入到对象中,并且进入函数,似乎没有任何工作:/你能举一个有效的例子吗? – Felix

+0

嗯。看起来您需要指定要隐式导入的Buildable的类型。你可以用'隐式'函数来做到这一点。或者当您试图对矩阵函数使用隐式参数时。我编辑了答案来纠正它。我相信还有更好的方法可以做到这一点。 – rjsvaljean

+0

一旦我回去工作,我会试试这个:) – Felix