0

我正在使用 scalacheck,现在正处于通用编程汤的中间。官方指南显示了这个例子:

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))
}

同时,对于我的测试,我需要一个 Array[Array[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,Array])org.scalacheck.Gen[Array[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 个隐式参数:/

4

1 回答 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]。一直到Buildablescalacheck 源代码中定义的 where ,我发现有一个对象 ( org.scalacheck.util.Buildable) 提供了Buildable为包括Array. 因此,您需要将其纳入范围。你可以这样做:

  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]
  }
于 2012-10-18T17:43:42.903 回答