falsify-0.4.0: Property-based testing with internal integrated shrinking
Safe HaskellNone
LanguageHaskell2010

Data.Falsify.ConcreteFun

Description

Concrete functions

Intended for qualified import.

import Data.Falsify.ConcreteFun ((:->)(..))
import qualified Data.Falsify.ConcreteFun as ConcreteFun
Synopsis

Documentation

data a :-> b where Source #

Concrete function

A concrete function is essentially a deep embedding: an explicit representation of the ouput value of the function for every input value in the function's domain.

Concrete functions are the central building block for generating random functions, as proposed by Koen Claessen in "Shrinking and showing functions", Haskell Symposium 2012 (https://dl.acm.org/doi/10.1145/2430532.2364516). Koen's key insight is that we can start with an infinite concrete function that is defined on every value in the input domain, but since in any given test that function is only applied to a finite number of inputs, we can then shrink the concrete function, throwing away entire chunks of the input domain, until we are left with a finite representation which can be printed as part of a test output.

All of the cleverness for generating concrete functions is about reducing the explicitly represented domain of the function. To shrink the outputs of the function nothing special is needed, and we can just rely on Haskell's laziness and the fact that falsify is carefully constructed so that it can generate infinite data types.

Constructors

Nil :: forall a b. a :-> b 
Unit :: forall b. b -> () :-> b 
Table :: forall a b. Ord a => Tree (a, Maybe b) -> a :-> b 
Sum :: forall a1 b b1. (a1 :-> b) -> (b1 :-> b) -> Either a1 b1 :-> b 
Prod :: forall a1 b1 b. (a1 :-> (b1 :-> b)) -> (a1, b1) :-> b 
Map :: forall a a1 b. (a -> a1) -> (a1 -> a) -> (a1 :-> b) -> a :-> b 

Instances

Instances details
Functor ((:->) a) Source # 
Instance details

Defined in Data.Falsify.ConcreteFun

Methods

fmap :: (a0 -> b) -> (a :-> a0) -> a :-> b #

(<$) :: a0 -> (a :-> b) -> a :-> a0 #

Construction

map :: (b -> a) -> (a -> b) -> (a :-> c) -> b :-> c Source #

Change domain of concrete function

This is the basic building block for constructing new concrete functions.

Application

apply :: (a :-> b) -> b -> a -> b Source #

Apply concrete function

Rendering

render :: (Show a, Show b) => (a :-> b) -> b -> String Source #

Show concrete function

Only use this on finite functions!