2016-08-07 32 views
2

Ich habe eine unveränderliche Datenstruktur in Scala, die eine Liste von Objekten enthält, die ich mit Scalacheck testen möchte.Warum gibt es keine FoldLeft oder Foreach auf Scalacheck Gen

Ein Insert für dieses Objekt gibt ein neues Objekt zurück. Wie füge ich mehrere Objekte in diese Datenstruktur ein? Mit anderen Worten, wie schreibe ich einen Generator für eine zufällige Instanz meiner Datenstruktur?

Wenn der Typ H [A], wobei A die Art von Objekt ist, habe ich versucht, etwas zu tun:

var heap = empty 
arbitrary[A] map (x => heap = insert(x, heap)) 

aber das hat nicht funktioniert.

+0

arbiträre [A] gibt Ihnen einen Generator von einer Sache, Sie können nicht wirklich über einen 'Int' falten. Sie könnten 'arbitrary [List [A]]' haben und dann einen Heap daraus machen, indem Sie fold on list verwenden oder Ihren Heap als (pseudocode) 'heap = insert (beliebiges [A], Heap) oder leer 'erzeugen –

Antwort

1

Dies ist eine sehr einfache, unveränderliche Datenstruktur ausgestattet mit einem insert Betrieb:

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) 

} 

Als einfaches Beispiel wollen wir sehen, wie man einen Generator von WrappedList[String] definieren könnte. Zuerst definieren einen Generator für ein List[String]:

val genStrings: Gen[List[String]] = 
    Gen.listOfN[String](10, Gen.oneOf("foo", "bar", "baz", "qux", "quux")) 

Dann definieren einen Generator von WrappedList[String] die durch genStrings eine Liste von Zeichenketten erzeugt erfolgt und umgeknickt wird dieser Liste jedes Element zum Einfügen in einen ursprünglich leeren WrappedList[String]:

val genWrappedListOfStrings = genStrings 
    .flatMap { _.foldRight(WrappedList.empty[String]) { (string, wrappedList) => 
     wrappedList insert string }} 

Sie sind fertig!

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) 

Beachten Sie, dass kein var erforderlich ist.