liveBook · Manning

Forall

As explained in Learn Haskell by Example

forAll is a QuickCheck combinator that attaches an explicitly supplied generator to a property test.

`forAll` is a QuickCheck combinator for running a property with a generator chosen explicitly for that property. It turns the generator-and-check pairing back into a `Property`, so custom test data can drive a normal QuickCheck test. section 9.4.1

The capitalization matters: `forAll` is the QuickCheck testing combinator, whereas lowercase `forall` is Haskell syntax whose meaning depends on enabled language extensions. Do not treat them as interchangeable. section 6.2.2 section 9.4.1

Use `forAll` when a property needs inputs with relationships that default generation does not guarantee:

  • Build a `Gen` value that produces the required input shape. section 9.4.1
  • Pass that generator and a predicate to `forAll`; the resulting value is again a `Property`. section 9.4.1
  • Move reusable generation into an `Arbitrary` instance when custom types need generators across many tests. section 9.4.1

Testing alphabet rotation with valid inputs

A rotation property needs a nonempty alphabet and a character drawn from that alphabet. The generator selects an alphabet, bounds the rotation by test size, selects a member character, and returns the triple. `forAll gen prop` then checks that `alphabetRot` returns a character still contained in the alphabet. section 9.4.1

Listing 9.18 Property describing closedness of the alphabet function
prop_alphabetRotClosed :: Property
prop_alphabetRotClosed =
  forAll gen prop  #1
  where
    prop :: (Alphabet, Int, Char) -> Bool
    prop (alphabet, n, c) =               #2
      let c' = alphabetRot alphabet n c   #2
       in c' `elem` alphabet              #2

    gen :: Gen (Alphabet, Int, Char)
    gen = do
      size <- getSize  #3
      alphabet <- arbitrary `suchThat` (not . null)  #4
      n <- choose (-size, size)  #5
      c <- elements alphabet  #6
      return (L.nub alphabet, n, c)  #7

The listing places `forAll gen prop` at the property boundary, keeping generation separate from the Boolean check while sharing a tuple-shaped test case. section 9.4.1

How Learn Haskell by Example covers it

How deep it goes
Shows a complete generator and property pairing, then defers reusable generation to `Arbitrary` instances.
Examples
Uses a nonempty alphabet, bounded rotation count, and selected alphabet character to test `alphabetRot` closedness.
What it assumes
Builds on creating a `Gen` generator and a predicate that accepts its generated value.
What you can do after
Apply it via QuickCheck to test a predicate against deliberately generated cases.
How it connects
Connects `forAll` with `Gen`, `Property`, `Arbitrary`, `getSize`, `choose`, and `elements`.

Also explained in

Compare how 2 books explain forall →

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.