liveBook · Manning

Shrinking

As explained in Learn Haskell by Example

Shrinking is the technique of systematically reducing a failing test input and rechecking it to find a smaller counterexample.

Shrinking reduces a failing property-test input and rechecks each smaller candidate. It continues until further reduction stops preserving the failure, producing a more understandable counterexample. section 9.4.3

QuickCheck applies shrinking in a repeatable sequence:

  • Find an input that falsifies the property. section 9.4.3
  • Generate smaller candidates, such as lower numeric values or shorter lists and maps. section 9.3.1
  • Recheck each candidate and retain reductions that remain counterexamples. section 9.4.3
  • Stop when no further reduction preserves the failure. section 9.4.3

A smaller rot13 counterexample

A faulty rot13 property may initially fail on a large string. QuickCheck reports a much clearer counterexample: "a", after two tests and one shrink. Repeated runs can produce the same counterexample, making the bug easier to reproduce and debug. section 9.3.1

Shrinking is defined through the Arbitrary type class. Its shrink function has type a -> [a], so it deterministically returns candidate reductions. For custom structures, shrink the underlying representation and rebuild valid values; an associative map can shrink its list of pairs while removing duplicate keys. section 9.4.3 section 9.4.3

ghci> shrink 'H'
"abchABC"
ghci> shrink 'A'
"abc"
ghci> shrink 'h'
"abc"
ghci> shrink '\n'
"abcABC123 "
ghci> shrink '1'
"abcABC"

Inspect concrete character reductions with shrink, including the candidate lists produced for 'H', 'A', 'h', newline, and '1'. section 9.4.3

How Learn Haskell by Example covers it

How deep it goes
Explains iterative rechecking, deterministic candidate generation, and custom Arbitrary instances for associative maps.
Examples
Uses faulty rot13 tests, character reductions, and an AssocMap shrink function as concrete demonstrations.
What it assumes
Assumes property tests and random inputs, while introducing shrinking and Arbitrary-based customization through examples.
What you can do after
Apply it via QuickCheck to obtain smaller failing inputs and define shrinking behavior for custom data types.
How it connects
Connects property testing with QuickCheck, counterexamples, the Arbitrary type class, and custom data-type shrinking.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.