Reputation: 547
I have an immutable datastructure in scala, that contains a list of objects, that i would like to test with scalacheck.
An insert on this object returns a new object. How do I insert multiple objects in this datastructure? With other words, how do I write a generator for a random instance of my datastructure?
If the type is H[A] where A is the type of object, I tried doing something like:
var heap = empty
arbitrary[A] map (x => heap = insert(x, heap))
but this did not work.
Upvotes: 2
Views: 163
Reputation: 66344
Here is a very simple, immutable data structure equipped with an insert
operation:
final class WrappedList[A] private (underlying: List[A]) {
def insert[B>:A](elem: B): WrappedList[B] = new WrappedList(elem :: underlying)
override def toString: String = "WrappedList(" + underlying.mkString(", ") + ")"
}
object WrappedList {
def empty[A]: WrappedList[A] = new WrappedList(Nil)
}
As a simple example, let's see how you could define a generator of WrappedList[String]
. First, define a generator for a List[String]
:
val genStrings: Gen[List[String]] =
Gen.listOfN[String](10, Gen.oneOf("foo", "bar", "baz", "qux", "quux"))
Then, define a generator of WrappedList[String]
that takes a list of strings generated by genStrings
, and folds over that list to insert each element in an initially empty WrappedList[String]
:
val genWrappedListOfStrings = genStrings
.flatMap { _.foldRight(WrappedList.empty[String]) { (string, wrappedList) =>
wrappedList insert string }}
You're done!
scala> genWrappedListOfStrings.sample.head
res0: WrappedList[String] = WrappedList(qux, bar, bar, baz, quux, foo, qux, qux, foo, qux)
scala> genWrappedListOfStrings.sample.head
res1: WrappedList[String] = WrappedList(qux, foo, qux, baz, qux, qux, quux, quux, qux, quux)
Note that there is no need for a var
.
Upvotes: 1