TheSeamau5 / elm-check

Property Based Testing in Elm
70 stars 20 forks source link

Investigate Clojure's test.check's shrinking method #5

Closed TheSeamau5 closed 9 years ago

TheSeamau5 commented 9 years ago

Clojure's test.check gets shrinking for free by fusing the generators and the shrinkers together.

The way they do this is by defining generators as follows:

type alias Generator a = Random.Generator (RoseTree a)

Where a rose tree is defined as:

type RoseTree a = Rose a (List (RoseTree a))

This would allow generators (currently Investigators) to be monads, functors, and all those nice things

TheSeamau5 commented 9 years ago

One thing that is key is for List to be lazy. If List is not lazy, then it gets really easy to use up too much memory as each generator contains also the entire shrink tree.

TheSeamau5 commented 9 years ago

Example code:

type alias Investigator a = Generator (RoseTree a)

type alias Shrinker a = a -> LazyList a

rt : Int -> Shrinker Int -> RoseTree Int
rt root shrinker =
  Rose root (LazyList.map (\r -> rt r shrinker) (shrinker root))

map : (a -> b) -> Investigator a -> Investigator b
map f invA =
  Random.map (RoseTree.map f) invA
TheSeamau5 commented 9 years ago

This will appear in the next version