I'm learning scala by reading the code from ScalaCheck and find many combinators are suffixed by suchThat
. However, in many cases suchThat doesn't look quite necessary. I'm wondering why they are designed in this way. Here's some excerpted from GitHub:
Example 1.
/** Picks a random value from a list */
def oneOf[T](xs: Seq[T]): Gen[T] =
choose(0, xs.size-1).map(xs(_)).suchThat(xs.contains)
map
picks an element from xs and therefore xs.contains
seems redundant.
--
Example 2.
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)
}
Why is c.size == n
needed, given that a successful sequence
would return in the length of n?
--
Example 3.
/** Generates a string of alpha characters */
def alphaStr: Gen[String] =
listOf(alphaChar).map(_.mkString).suchThat(_.forall(_.isLetter))
Generated strings would consist of list of alphaChar
which is chosen from uppercase and lowercase letters. Why do we need a suchThat
to check isLetter again?
--
See https://github.com/rickynils/scalacheck/commit/2d92eb61a89a8ec2e16d0af8599f9baafc9b5418
Basically, this is needed for the ScalaCheck test case simplification to know what bounds the generated values originally had.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With