2012-10-18 48 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