Copyright | (c) 2015-2018 Rudy Matela |
---|---|
License | 3-Clause BSD (see the file LICENSE) |
Maintainer | Rudy Matela <rudy@matela.com.br> |
Safe Haskell | None |
Language | Haskell2010 |
This module is part of LeanCheck, a simple enumerative property-based testing library.
This module re-exports Test.LeanCheck but some test functions have been specialized to catch errors (see the explicit export list below).
This module is unsafe as it uses unsafePerformIO
to catch errors.
Synopsis
- holds :: Testable a => Int -> a -> Bool
- fails :: Testable a => Int -> a -> Bool
- exists :: Testable a => Int -> a -> Bool
- counterExample :: Testable a => Int -> a -> Maybe [String]
- counterExamples :: Testable a => Int -> a -> [[String]]
- witness :: Testable a => Int -> a -> Maybe [String]
- witnesses :: Testable a => Int -> a -> [[String]]
- results :: Testable a => a -> [([String], Bool)]
- fromError :: a -> a -> a
- errorToNothing :: a -> Maybe a
- errorToFalse :: Bool -> Bool
- errorToTrue :: Bool -> Bool
- anyErrorToNothing :: a -> Maybe a
- class Testable a
- class Listable a where
- toTiers :: [a] -> [[a]]
- listIntegral :: (Enum a, Num a) => [a]
- tiersFractional :: Fractional a => [[a]]
- mapT :: (a -> b) -> [[a]] -> [[b]]
- filterT :: (a -> Bool) -> [[a]] -> [[a]]
- concatT :: [[[[a]]]] -> [[a]]
- concatMapT :: (a -> [[b]]) -> [[a]] -> [[b]]
- cons0 :: a -> [[a]]
- cons1 :: Listable a => (a -> b) -> [[b]]
- cons2 :: (Listable a, Listable b) => (a -> b -> c) -> [[c]]
- cons3 :: (Listable a, Listable b, Listable c) => (a -> b -> c -> d) -> [[d]]
- cons4 :: (Listable a, Listable b, Listable c, Listable d) => (a -> b -> c -> d -> e) -> [[e]]
- cons5 :: (Listable a, Listable b, Listable c, Listable d, Listable e) => (a -> b -> c -> d -> e -> f) -> [[f]]
- delay :: [[a]] -> [[a]]
- reset :: [[a]] -> [[a]]
- suchThat :: [[a]] -> (a -> Bool) -> [[a]]
- (+|) :: [a] -> [a] -> [a]
- (\/) :: [[a]] -> [[a]] -> [[a]]
- (\\//) :: [[a]] -> [[a]] -> [[a]]
- (><) :: [[a]] -> [[b]] -> [[(a, b)]]
- productWith :: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]]
- (==>) :: Bool -> Bool -> Bool
- cons6 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f) => (a -> b -> c -> d -> e -> f -> g) -> [[g]]
- cons7 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g) => (a -> b -> c -> d -> e -> f -> g -> h) -> [[h]]
- cons8 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h) => (a -> b -> c -> d -> e -> f -> g -> h -> i) -> [[i]]
- cons9 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> [[j]]
- cons10 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> [[k]]
- cons11 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l) -> [[l]]
- cons12 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k, Listable l) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m) -> [[m]]
- ofWeight :: [[a]] -> Int -> [[a]]
- addWeight :: [[a]] -> Int -> [[a]]
- deriveListable :: Name -> DecsQ
- deriveListableCascading :: Name -> DecsQ
- check :: Testable a => a -> IO ()
- checkFor :: Testable a => Int -> a -> IO ()
- checkResult :: Testable a => a -> IO Bool
- checkResultFor :: Testable a => Int -> a -> IO Bool
- bagCons :: Listable a => ([a] -> b) -> [[b]]
- setCons :: Listable a => ([a] -> b) -> [[b]]
- mapCons :: (Listable a, Listable b) => ([(a, b)] -> c) -> [[c]]
- noDupListCons :: Listable a => ([a] -> b) -> [[b]]
- product3With :: (a -> b -> c -> d) -> [[a]] -> [[b]] -> [[c]] -> [[d]]
- productMaybeWith :: (a -> b -> Maybe c) -> [[a]] -> [[b]] -> [[c]]
- listsOf :: [[a]] -> [[[a]]]
- products :: [[[a]]] -> [[[a]]]
- deleteT :: Eq a => a -> [[a]] -> [[a]]
- normalizeT :: [[a]] -> [[a]]
- noDupListsOf :: [[a]] -> [[[a]]]
- bagsOf :: [[a]] -> [[[a]]]
- setsOf :: [[a]] -> [[[a]]]
- listsOfLength :: Int -> [[a]] -> [[[a]]]
Documentation
errorToNothing :: a -> Maybe a Source #
errorToFalse :: Bool -> Bool Source #
errorToTrue :: Bool -> Bool Source #
anyErrorToNothing :: a -> Maybe a Source #
class Listable a where Source #
A type is Listable
when there exists a function that
is able to list (ideally all of) its values.
Ideally, instances should be defined by a tiers
function that
returns a (potentially infinite) list of finite sub-lists (tiers):
the first sub-list contains elements of size 0,
the second sub-list contains elements of size 1
and so on.
Size here is defined by the implementor of the type-class instance.
For algebraic data types, the general form for tiers
is
tiers = cons<N> ConstructorA \/ cons<N> ConstructorB \/ ... \/ cons<N> ConstructorZ
where N
is the number of arguments of each constructor A...Z
.
Instances can be alternatively defined by list
.
In this case, each sub-list in tiers
is a singleton list
(each succeeding element of list
has +1 size).
The function deriveListable
from Test.LeanCheck.Derive
can automatically derive instances of this typeclass.
A Listable
instance for functions is also available but is not exported by
default. Import Test.LeanCheck.Function if you need to test higher-order
properties.
Instances
Listable Bool Source # | tiers :: [[Bool]] = [[False,True]] list :: [[Bool]] = [False,True] |
Listable Char Source # | |
Listable Double Source # | |
Listable Float Source # | |
Listable Int Source # | tiers :: [[Int]] = [[0], [1], [-1], [2], [-2], [3], [-3], ...] list :: [Int] = [0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, ...] |
Listable Integer Source # | |
Listable Ordering Source # | |
Listable Word Source # | |
Listable () Source # | |
Listable Nat7 Source # | |
Listable Nat6 Source # | |
Listable Nat5 Source # | |
Listable Nat4 Source # | |
Listable Nat3 Source # | |
Listable Nat2 Source # | |
Listable Nat1 Source # | |
Listable Nat Source # | |
Listable Natural Source # | |
Listable Word4 Source # | |
Listable Word3 Source # | |
Listable Word2 Source # | |
Listable Word1 Source # | |
Listable Int4 Source # | |
Listable Int3 Source # | |
Listable Int2 Source # | |
Listable Int1 Source # | |
Listable a => Listable [a] Source # | tiers :: [[ [Int] ]] = [ [ [] ] , [ [0] ] , [ [0,0], [1] ] , [ [0,0,0], [0,1], [1,0], [-1] ] , ... ] list :: [ [Int] ] = [ [], [0], [0,0], [1], [0,0,0], ... ] |
Listable a => Listable (Maybe a) Source # | tiers :: [[Maybe Int]] = [[Nothing], [Just 0], [Just 1], ...] tiers :: [[Maybe Bool]] = [[Nothing], [Just False, Just True]] |
(Integral a, Listable a) => Listable (Ratio a) Source # | |
(Integral a, Bounded a) => Listable (Xs a) Source # | Lists with elements of the |
(Integral a, Bounded a) => Listable (X a) Source # | Extremily large integers are intercalated with small integers. list :: [X Int] = map X [ 0, 1, -1, maxBound, minBound , 2, -2, maxBound-1, minBound+1 , 3, -3, maxBound-2, minBound+2 , ... ] |
Listable a => Listable (Set a) Source # | |
Listable a => Listable (Bag a) Source # | |
Listable a => Listable (NoDup a) Source # | |
(Eq a, Listable a, Listable b) => Listable (a -> b) Source # | |
(Eq a, Eq b, Listable a, Listable b) => Listable (a -> b) Source # | |
(FunListable a, Listable b) => Listable (a -> b) Source # | |
(Eq a, Listable a, CoListable a, Listable b) => Listable (a -> b) Source # | |
(CoListable a, Listable b) => Listable (a -> b) Source # | |
(Listable a, Listable b) => Listable (Either a b) Source # | |
(Listable a, Listable b) => Listable (a, b) Source # | tiers :: [[(Int,Int)]] = [ [(0,0)] , [(0,1),(1,0)] , [(0,-1),(1,1),(-1,0)] , ...] list :: [(Int,Int)] = [ (0,0), (0,1), (1,0), (0,-1), (1,1), ...] |
(Listable a, Listable b) => Listable (Map a b) Source # | |
(Listable a, Listable b, Listable c) => Listable (a, b, c) Source # | |
(Listable a, Listable b, Listable c, Listable d) => Listable (a, b, c, d) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e) => Listable (a, b, c, d, e) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f) => Listable (a, b, c, d, e, f) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g) => Listable (a, b, c, d, e, f, g) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h) => Listable (a, b, c, d, e, f, g, h) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i) => Listable (a, b, c, d, e, f, g, h, i) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j) => Listable (a, b, c, d, e, f, g, h, i, j) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k) => Listable (a, b, c, d, e, f, g, h, i, j, k) Source # | |
(Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k, Listable l) => Listable (a, b, c, d, e, f, g, h, i, j, k, l) Source # | |
toTiers :: [a] -> [[a]] Source #
Takes a list of values xs
and transform it into tiers on which each
tier is occupied by a single element from xs
.
To convert back to a list, just concat
.
listIntegral :: (Enum a, Num a) => [a] Source #
tiersFractional :: Fractional a => [[a]] Source #
Tiers of Fractional
values.
This can be used as the implementation of tiers
for Fractional
types.
concatMapT :: (a -> [[b]]) -> [[a]] -> [[b]] Source #
concatMap
over tiers
Given a constructor with no arguments,
returns tiers
of all possible applications of this constructor.
Since in this case there is only one possible application (to no
arguments), only a single value, of size/weight 0, will be present in the
resulting list of tiers.
cons3 :: (Listable a, Listable b, Listable c) => (a -> b -> c -> d) -> [[d]] Source #
Returns tiers of applications of a 3-argument constructor.
cons4 :: (Listable a, Listable b, Listable c, Listable d) => (a -> b -> c -> d -> e) -> [[e]] Source #
Returns tiers of applications of a 4-argument constructor.
cons5 :: (Listable a, Listable b, Listable c, Listable d, Listable e) => (a -> b -> c -> d -> e -> f) -> [[f]] Source #
Returns tiers of applications of a 5-argument constructor.
Test.LeanCheck.Basic defines
cons6
up to cons12
.
Those are exported by default from Test.LeanCheck,
but are hidden from the Haddock documentation.
reset :: [[a]] -> [[a]] Source #
Resets any delays in a list-of tiers
.
Conceptually this function makes a constructor "weightless",
assuring the first tier is non-empty.
Typically used when defining Listable instances:
reset (cons<N> <Constr>)
Be careful: do not apply reset
to recursive data structure
constructors. In general this will make the list of size 0 infinite,
breaking the tiers
invariant (each tier must be finite).
suchThat :: [[a]] -> (a -> Bool) -> [[a]] Source #
Tiers of values that follow a property
cons<N> `suchThat` condition
(+|) :: [a] -> [a] -> [a] infixr 5 Source #
Lazily interleaves two lists, switching between elements of the two. Union/sum of the elements in the lists.
[x,y,z] +| [a,b,c] == [x,a,y,b,z,c]
(\/) :: [[a]] -> [[a]] -> [[a]] infixr 7 Source #
Append tiers --- sum of two tiers enumerations.
[xs,ys,zs,...] \/ [as,bs,cs,...] = [xs++as,ys++bs,zs++cs,...]
(\\//) :: [[a]] -> [[a]] -> [[a]] infixr 7 Source #
Interleave tiers --- sum of two tiers enumerations.
When in doubt, use \/
instead.
[xs,ys,zs,...] \/ [as,bs,cs,...] = [xs+|as,ys+|bs,zs+|cs,...]
(><) :: [[a]] -> [[b]] -> [[(a, b)]] infixr 8 Source #
Take a tiered product of lists of tiers.
[t0,t1,t2,...] >< [u0,u1,u2,...] = [ t0**u0 , t0**u1 ++ t1**u0 , t0**u2 ++ t1**u1 ++ t2**u0 , ... ... ... ... ] where xs ** ys = [(x,y) | x <- xs, y <- ys]
Example:
[[0],[1],[2],...] >< [[0],[1],[2],...] == [ [(0,0)] , [(1,0),(0,1)] , [(2,0),(1,1),(0,2)] , [(3,0),(2,1),(1,2),(0,3)] ... ]
productWith :: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]] Source #
Take a tiered product of lists of tiers.
productWith
can be defined by ><
, as:
productWith f xss yss = map (uncurry f) $ xss >< yss
(==>) :: Bool -> Bool -> Bool infixr 0 Source #
Boolean implication operator. Useful for defining conditional properties:
prop_something x y = condition x y ==> something x y
cons6 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f) => (a -> b -> c -> d -> e -> f -> g) -> [[g]] Source #
cons7 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g) => (a -> b -> c -> d -> e -> f -> g -> h) -> [[h]] Source #
cons8 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h) => (a -> b -> c -> d -> e -> f -> g -> h -> i) -> [[i]] Source #
cons9 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> [[j]] Source #
cons10 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> [[k]] Source #
cons11 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l) -> [[l]] Source #
cons12 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k, Listable l) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m) -> [[m]] Source #
ofWeight :: [[a]] -> Int -> [[a]] Source #
Resets the weight of a constructor (or tiers) Typically used as an infix constructor when defining Listable instances:
cons<N> `ofWeight` <W>
Be careful: do not apply
to recursive data structure
constructors. In general this will make the list of size 0 infinite,
breaking the tier invariant (each tier must be finite).ofWeight
0
deriveListable :: Name -> DecsQ Source #
Derives a Listable
instance for a given type Name
.
Consider the following Stack
datatype:
data Stack a = Stack a (Stack a) | Empty
Writing
deriveListable ''Stack
will automatically derive the following Listable
instance:
instance Listable a => Listable (Stack a) where tiers = cons2 Stack \/ cons0 Empty
Warning: if the values in your type need to follow a data invariant, the derived instance won't respect it. Use this only on "free" datatypes.
Needs the TemplateHaskell
extension.
deriveListableCascading :: Name -> DecsQ Source #
Derives a Listable
instance for a given type Name
cascading derivation of type arguments as well.
Consider the following series of datatypes:
data Position = CEO | Manager | Programmer data Person = Person { name :: String , age :: Int , position :: Position } data Company = Company { name :: String , employees :: [Person] }
Writing
deriveListableCascading ''Company
will automatically derive the following three Listable
instances:
instance Listable Position where tiers = cons0 CEO \/ cons0 Manager \/ cons0 Programmer instance Listable Person where tiers = cons3 Person instance Listable Company where tiers = cons2 Company
check :: Testable a => a -> IO () Source #
Checks a property printing results on stdout
> check $ \xs -> sort (sort xs) == sort (xs::[Int]) +++ OK, passed 200 tests. > check $ \xs ys -> xs `union` ys == ys `union` (xs::[Int]) *** Failed! Falsifiable (after 4 tests): [] [0,0]
checkFor :: Testable a => Int -> a -> IO () Source #
Check a property for a given number of tests
printing results on stdout
bagCons :: Listable a => ([a] -> b) -> [[b]] Source #
Given a constructor that takes a bag of elements (as a list), lists tiers of applications of this constructor.
For example, a Bag
represented as a list.
bagCons Bag
setCons :: Listable a => ([a] -> b) -> [[b]] Source #
Given a constructor that takes a set of elements (as a list), lists tiers of applications of this constructor.
A naive Listable
instance for the Set
(of Data.Set)
would read:
instance Listable a => Listable (Set a) where tiers = cons0 empty \/ cons2 insert
The above instance has a problem: it generates repeated sets. A more efficient implementation that does not repeat sets is given by:
tiers = setCons fromList
Alternatively, you can use setsOf
direclty.
mapCons :: (Listable a, Listable b) => ([(a, b)] -> c) -> [[c]] Source #
Given a constructor that takes a map of elements (encoded as a list), lists tiers of applications of this constructor
So long as the underlying Listable
enumerations have no repetitions,
this will generate no repetitions.
This allows defining an efficient implementation of tiers
that does not
repeat maps given by:
tiers = mapCons fromList
noDupListCons :: Listable a => ([a] -> b) -> [[b]] Source #
Given a constructor that takes a list with no duplicate elements, return tiers of applications of this constructor.
product3With :: (a -> b -> c -> d) -> [[a]] -> [[b]] -> [[c]] -> [[d]] Source #
Like productWith
, but over 3 lists of tiers.
productMaybeWith :: (a -> b -> Maybe c) -> [[a]] -> [[b]] -> [[c]] Source #
listsOf :: [[a]] -> [[[a]]] Source #
Takes as argument tiers of element values; returns tiers of lists of elements.
listsOf [[]] == [[[]]]
listsOf [[x]] == [ [[]] , [[x]] , [[x,x]] , [[x,x,x]] , ... ]
listsOf [[x],[y]] == [ [[]] , [[x]] , [[x,x],[y]] , [[x,x,x],[x,y],[y,x]] , ... ]
products :: [[[a]]] -> [[[a]]] Source #
Takes the product of N lists of tiers, producing lists of length N.
Alternatively, takes as argument a list of lists of tiers of elements; returns lists combining elements of each list of tiers.
products [xss] = mapT (:[]) xss products [xss,yss] = mapT (\(x,y) -> [x,y]) (xss >< yss) products [xss,yss,zss] = product3With (\x y z -> [x,y,z]) xss yss zss
deleteT :: Eq a => a -> [[a]] -> [[a]] Source #
Delete the first occurence of an element in a tier.
For normalized lists-of-tiers without repetitions, the following holds:
deleteT x = normalizeT . (`suchThat` (/= x))
normalizeT :: [[a]] -> [[a]] Source #
Normalizes tiers by removing up to 12 empty tiers from the end of a list of tiers.
normalizeT [xs0,xs1,...,xsN,[]] = [xs0,xs1,...,xsN] normalizeT [xs0,xs1,...,xsN,[],[]] = [xs0,xs1,...,xsN]
The arbitrary limit of 12 tiers is necessary as this function would loop if there is an infinite trail of empty tiers.
noDupListsOf :: [[a]] -> [[[a]]] Source #
Takes as argument tiers of element values; returns tiers of lists with no repeated elements.
noDupListsOf [[0],[1],[2],...] == [ [[]] , [[0]] , [[1]] , [[0,1],[1,0],[2]] , [[0,2],[2,0],[3]] , ... ]
bagsOf :: [[a]] -> [[[a]]] Source #
Takes as argument tiers of element values; returns tiers of size-ordered lists of elements possibly with repetition.
bagsOf [[0],[1],[2],...] = [ [[]] , [[0]] , [[0,0],[1]] , [[0,0,0],[0,1],[2]] , [[0,0,0,0],[0,0,1],[0,2],[1,1],[3]] , [[0,0,0,0,0],[0,0,0,1],[0,0,2],[0,1,1],[0,3],[1,2],[4]] , ... ]
setsOf :: [[a]] -> [[[a]]] Source #
Takes as argument tiers of element values; returns tiers of size-ordered lists of elements without repetition.
setsOf [[0],[1],[2],...] = [ [[]] , [[0]] , [[1]] , [[0,1],[2]] , [[0,2],[3]] , [[0,3],[1,2],[4]] , [[0,1,2],[0,4],[1,3],[5]] , ... ]
Can be used in the constructor of specialized Listable
instances.
For Set
(from Data.Set), we would have:
instance Listable a => Listable (Set a) where tiers = mapT fromList $ setsOf tiers
listsOfLength :: Int -> [[a]] -> [[[a]]] Source #
Takes as argument an integer length and tiers of element values; returns tiers of lists of element values of the given length.
listsOfLength 3 [[0],[1],[2],[3],[4]...] = [ [[0,0,0]] , [[0,0,1],[0,1,0],[1,0,0]] , [[0,0,2],[0,1,1],[0,2,0],[1,0,1],[1,1,0],[2,0,0]] , ... ]