diff --git a/src/main/scala/org/scalacheck/Arbitrary.scala b/src/main/scala/org/scalacheck/Arbitrary.scala
index 15774a72b..63d2865d1 100644
--- a/src/main/scala/org/scalacheck/Arbitrary.scala
+++ b/src/main/scala/org/scalacheck/Arbitrary.scala
@@ -268,16 +268,18 @@ object Arbitrary {
implicit def arbEither[T, U](implicit at: Arbitrary[T], au: Arbitrary[U]): Arbitrary[Either[T, U]] =
Arbitrary(oneOf(arbitrary[T].map(Left(_)), arbitrary[U].map(Right(_))))
- /** Arbitrary instance of any [[org.scalacheck.util.Buildable]] container (such as lists, arrays,
- * streams, etc). The maximum size of the container depends on the size
- * generation parameter. */
- implicit def arbContainer[C[_],T](implicit a: Arbitrary[T], b: Buildable[T,C]
+ /** Arbitrary instance of any [[org.scalacheck.util.Buildable]] container
+ * (such as lists, arrays, streams, etc). The maximum size of the container
+ * depends on the size generation parameter. */
+ implicit def arbContainer[C[_],T](implicit
+ a: Arbitrary[T], b: Buildable[T,C], t: C[T] => Traversable[T]
): Arbitrary[C[T]] = Arbitrary(containerOf[C,T](arbitrary[T]))
- /** Arbitrary instance of any [[org.scalacheck.util.Buildable2]] container (such as maps, etc).
- * The maximum size of the container depends on the size
+ /** Arbitrary instance of any [[org.scalacheck.util.Buildable2]] container
+ * (such as maps, etc). The maximum size of the container depends on the size
* generation parameter. */
- implicit def arbContainer2[C[_,_],T,U](implicit a: Arbitrary[(T,U)], b: Buildable2[T,U,C]
+ implicit def arbContainer2[C[_,_],T,U](implicit
+ a: Arbitrary[(T,U)], b: Buildable2[T,U,C], t: C[T,U] => Traversable[(T,U)]
): Arbitrary[C[T,U]] = Arbitrary(containerOf[C,T,U](arbitrary[(T,U)]))
// Functions //
diff --git a/src/main/scala/org/scalacheck/Gen.scala b/src/main/scala/org/scalacheck/Gen.scala
index 6eb155bb5..e660349cf 100644
--- a/src/main/scala/org/scalacheck/Gen.scala
+++ b/src/main/scala/org/scalacheck/Gen.scala
@@ -266,10 +266,7 @@ object Gen {
case (rs,g) => g.doApply(p).flatMap(r => rs.map(_ :+ r))
}
}
- val sieve = gs.foldLeft((_:T) => false) { case (s,g) =>
- x:T => s(x) || g.sieveCopy(x)
- }
- g.map(b.fromIterable) // TODO .suchThat(_.forall(sieve))
+ g.map(b.fromIterable)
}
/** Sequences generators. If any of the given generators fails, the
@@ -280,10 +277,7 @@ object Gen {
case (rs,g) => g.doApply(p).flatMap(r => rs.map(_ :+ r))
}
}
- val sieve = gs.foldLeft((_:T) => false) { case (s,g) =>
- x:T => s(x) || g.sieveCopy(x)
- }
- g.map(b.fromIterable) // TODO .suchThat(_.forall(sieve))
+ g.map(b.fromIterable)
}
/** Wraps a generator lazily. The given parameter is only evaluated once,
@@ -348,57 +342,84 @@ object Gen {
//// List Generators ////
- /** Generates a container of any type for which there exists an implicit
+ /** Generates a container of any Traversable type for which there exists an implicit
* [[org.scalacheck.util.Buildable]] instance. The elements in the container will
* be generated by the given generator. The size of the generated container
* is given by `n`. If the given generator fails generating a value, the
- * complete container gnerator will also fail. */
- def containerOfN[C[_],T](n: Int, g: Gen[T])(implicit b: Buildable[T,C]
- ): Gen[C[T]] = sequence[C,T](Traversable.fill(n)(g))
-
- /** Generates a container of any type for which there exists an implicit
- * [[org.scalacheck.util.Buildable]] instance. The elements in the container
- * will be generated by the given generator. The size of the container is
- * bounded by the size parameter used when generating values. */
- def containerOf[C[_],T](g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] =
- sized(size => choose(0,size).flatMap(containerOfN[C,T](_,g)))
+ * complete container generator will also fail. */
+ def containerOfN[C[_],T](n: Int, g: Gen[T])(implicit
+ evb: Buildable[T,C], evt: C[T] => Traversable[T]
+ ): Gen[C[T]] =
+ sequence[C,T](Traversable.fill(n)(g)) suchThat { c =>
+ c.size == n && c.forall(g.sieveCopy)
+ }
- /** Generates a non-empty container of any type for which there exists an
+ /** Generates a container of any Traversable type for which there exists an
* implicit [[org.scalacheck.util.Buildable]] instance. The elements in the
* container will be generated by the given generator. The size of the
* container is bounded by the size parameter used when generating values. */
- def nonEmptyContainerOf[C[_],T](g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] =
- sized(size => choose(1,size).flatMap(containerOfN[C,T](_,g)))
+ def containerOf[C[_],T](g: Gen[T])(implicit
+ evb: Buildable[T,C], evt: C[T] => Traversable[T]
+ ): Gen[C[T]] =
+ sized(s => choose(0,s).flatMap(containerOfN[C,T](_,g))) suchThat { c =>
+ c.forall(g.sieveCopy)
+ }
- /** Generates a non-empty container of any type for which there exists an
- * implicit [[org.scalacheck.util.Buildable]] instance. The elements in the
- * container will be generated by the given generator. The size of the
- * container is bounded by the size parameter used when generating values. */
- @deprecated("Use Gen.nonEmptyContainerOf instead", "1.11.0")
- def containerOf1[C[_],T](g: Gen[T])(implicit b: Buildable[T,C]): Gen[C[T]] =
- nonEmptyContainerOf[C,T](g)
+ /** Generates a non-empty container of any Traversable type for which there
+ * exists an implicit [[org.scalacheck.util.Buildable]] instance. The
+ * elements in the container will be generated by the given generator. The
+ * size of the container is bounded by the size parameter used when
+ * generating values. */
+ def nonEmptyContainerOf[C[_],T](g: Gen[T])(implicit
+ evb: Buildable[T,C], evt: C[T] => Traversable[T]
+ ): Gen[C[T]] =
+ sized(s => choose(1,s).flatMap(containerOfN[C,T](_,g))) suchThat { c =>
+ c.size > 0 && c.forall(g.sieveCopy)
+ }
- /** Generates a container of any type for which there exists an implicit
- * [[org.scalacheck.util.Buildable2]] instance. The elements in the container will
- * be generated by the given generator. The size of the generated container
- * is given by `n`. If the given generator fails generating a value, the
- * complete container gnerator will also fail. */
- def containerOfN[C[_,_],T,U](n: Int, g: Gen[(T,U)])(implicit b: Buildable2[T,U,C]
- ): Gen[C[T,U]] = sequence[C,T,U](Traversable.fill(n)(g))
+ /** Generates a non-empty container of any Traversable type for which there
+ * exists an implicit [[org.scalacheck.util.Buildable]] instance. The
+ * elements in the container will be generated by the given generator. The
+ * size of the container is bounded by the size parameter used when
+ * generating values. */
+ @deprecated("Use Gen.nonEmptyContainerOf instead", "1.11.0")
+ def containerOf1[C[_],T](g: Gen[T])(implicit
+ evb: Buildable[T,C], evt: C[T] => Traversable[T]
+ ): Gen[C[T]] = nonEmptyContainerOf[C,T](g)
+
+ /** Generates a container of any Traversable type for which there exists an
+ * implicit [[org.scalacheck.util.Buildable2]] instance. The elements in
+ * the container will be generated by the given generator. The size of the
+ * generated container is given by `n`. If the given generator fails
+ * generating a value, the complete container generator will also fail. */
+ def containerOfN[C[_,_],T,U](n: Int, g: Gen[(T,U)])(implicit
+ evb: Buildable2[T,U,C], evt: C[T,U] => Traversable[(T,U)]
+ ): Gen[C[T,U]] =
+ sequence[C,T,U](Traversable.fill(n)(g)).suchThat { c =>
+ c.size == n && c.forall(g.sieveCopy)
+ }
- /** Generates a container of any type for which there exists an implicit
- * Buildable2
instance. The elements in the container will
- * be generated by the given generator. The size of the container is
- * bounded by the size parameter used when generating values. */
- def containerOf[C[_,_],T,U](g: Gen[(T,U)])(implicit b: Buildable2[T,U,C]): Gen[C[T,U]] =
- sized(size => for(n <- choose(0,size); c <- containerOfN[C,T,U](n,g)) yield c)
+ /** Generates a container of any Traversable type for which there exists
+ * an implicit Buildable2
instance. The elements in the
+ * container will be generated by the given generator. The size of the
+ * container is bounded by the size parameter used when generating values. */
+ def containerOf[C[_,_],T,U](g: Gen[(T,U)])(implicit
+ evb: Buildable2[T,U,C], evt: C[T,U] => Traversable[(T,U)]
+ ): Gen[C[T,U]] =
+ sized(s => choose(0,s).flatMap(containerOfN[C,T,U](_,g))) suchThat { c =>
+ c.forall(g.sieveCopy)
+ }
/** Generates a non-empty container of any type for which there exists an
* implicit Buildable2
instance. The elements in the container
* will be generated by the given generator. The size of the container is
* bounded by the size parameter used when generating values. */
- def nonEmptyContainerOf[C[_,_],T,U](g: Gen[(T,U)])(implicit b: Buildable2[T,U,C]): Gen[C[T,U]] =
- sized(size => for(n <- choose(1,size); c <- containerOfN[C,T,U](n,g)) yield c)
+ def nonEmptyContainerOf[C[_,_],T,U](g: Gen[(T,U)])(implicit
+ evb: Buildable2[T,U,C], evt: C[T,U] => Traversable[(T,U)]
+ ): Gen[C[T,U]] =
+ sized(s => choose(1,s).flatMap(containerOfN[C,T,U](_,g))) suchThat { c =>
+ c.size > 0 && c.forall(g.sieveCopy)
+ }
/** Generates a list of random length. The maximum length depends on the
* size parameter. This method is equal to calling
@@ -482,16 +503,18 @@ object Gen {
/* Generates a string that starts with a lower-case alpha character,
* and only contains alphanumerical characters */
- def identifier: Gen[String] = for {
+ def identifier: Gen[String] = (for {
c <- alphaLowerChar
cs <- listOf(alphaNumChar)
- } yield (c::cs).mkString // TODO suchThat
+ } yield (c::cs).mkString).suchThat(_.forall(c => c.isLetter || c.isDigit))
/* Generates a string of alpha characters */
- def alphaStr: Gen[String] = listOf(alphaChar).map(_.mkString) // TODO suchThat
+ def alphaStr: Gen[String] =
+ listOf(alphaChar).map(_.mkString).suchThat(_.forall(_.isLetter))
/* Generates a string of digits */
- def numStr: Gen[String] = listOf(numChar).map(_.mkString) // TODO suchThat
+ def numStr: Gen[String] =
+ listOf(numChar).map(_.mkString).suchThat(_.forall(_.isDigit))
//// Number Generators ////
diff --git a/src/main/scala/org/scalacheck/util/Buildable.scala b/src/main/scala/org/scalacheck/util/Buildable.scala
index fac8b0a50..eb959ee6a 100644
--- a/src/main/scala/org/scalacheck/util/Buildable.scala
+++ b/src/main/scala/org/scalacheck/util/Buildable.scala
@@ -18,7 +18,6 @@ trait Buildable[T,C[_]] {
b ++= it
b.result()
}
- // TODO def toIterable
}
trait Buildable2[T,U,C[_,_]] {
diff --git a/src/test/scala/org/scalacheck/util/BuildableSpecification.scala b/src/test/scala/org/scalacheck/util/BuildableSpecification.scala
index f44bf474e..4f23462e1 100644
--- a/src/test/scala/org/scalacheck/util/BuildableSpecification.scala
+++ b/src/test/scala/org/scalacheck/util/BuildableSpecification.scala
@@ -13,8 +13,10 @@ package util
import collection._
object BuildableSpecification {
- def container[C[_]](implicit ev: Buildable[String, C]) =
- Gen.containerOf[C, String](Gen.alphaStr)
+ def container[C[_]](implicit
+ evb: Buildable[String, C],
+ evt: C[String] => Traversable[String]
+ ) = Gen.containerOf[C, String](Gen.alphaStr)
implicit val listGen: Gen[List[String]] = container[List]
@@ -41,4 +43,4 @@ object BuildableSpecification {
implicit val iterableGen: Gen[immutable.Iterable[String]] = container[immutable.Iterable]
implicit val trieIteratorGen: Gen[immutable.Queue[String]] = container[immutable.Queue]
-}
\ No newline at end of file
+}