-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Functional enumeration for systematic and random testing -- -- Feat (Functional Enumeration of Abstract Types) provides an -- enumeration as a function from natural numbers to values (similar to -- toEnum). This can be used both for SmallCheck-style -- systematic testing and QuickCheck style random testing, and hybrids of -- the two. -- -- The enumerators are defined in a very boilerplate manner and there is -- a Template Haskell script for deriving the class instance for most -- types. Test.Feat contain a subset of the other modules that -- should be sufficient for most test usage. There is a large scale -- example in the tar ball (testing the Template Haskell pretty printer). @package testing-feat @version 0.1 -- | A monad for binding values to tags to ensure sharing, with the added -- twist that the value can be polymorphic and each monomorphic instance -- is bound separately. module Control.Monad.TagShare -- | A dynamic map with type safe insertion and lookup. data DynMap tag dynEmpty :: DynMap tag dynInsert :: (Typeable a, Ord tag) => tag -> a -> DynMap tag -> DynMap tag dynLookup :: (Typeable a, Ord tag) => tag -> DynMap tag -> Maybe a -- | A sharing monad with a function that binds a tag to a value. type Sharing tag a = State (DynMap tag) a runSharing :: Sharing tag a -> a share :: (Typeable a, Ord tag) => tag -> Sharing tag a -> Sharing tag a instance Show tag => Show (DynMap tag) -- | Basic combinators fo building enumerations most users will want to use -- the type class based combinators in Test.Feat.Class instead. module Test.Feat.Enumerate type Part = Int type Index = Integer -- | A functional enumeration of type t is a partition of t into finite -- numbered sets called Parts. The number that identifies each part is -- called the cost of the values in that part. data Enumerate a Enumerate :: (Part -> Index) -> (Part -> Index -> a) -> Sharing Tag (Enumerate a) -> Enumerate a -- | Computes the cardinality of a given part. card :: Enumerate a -> Part -> Index -- | Selects a value from the enumeration For select e p i, -- i should be less than card e p select :: Enumerate a -> Part -> Index -> a -- | A self-optimising function. optimal :: Enumerate a -> Sharing Tag (Enumerate a) -- | Increases the cost of all values in an enumeration by one. pay :: Enumerate a -> Enumerate a mem :: Enumerate a -> Enumerate a -- | A conventient combination of memoisation and guarded recursion. mempay :: Enumerate a -> Enumerate a data Tag Source :: String -> String -> Int -> Int -> Tag tag :: Q Exp tagShare :: Typeable a => Tag -> Enumerate a -> Enumerate a optimise :: Enumerate a -> Enumerate a instance Typeable1 Enumerate instance Applicative Enumerate instance Monoid (Enumerate a) instance Functor Enumerate -- | Everything you need to construct an enumeration for an algebraic type. -- Just define each constructor using pure for nullary constructors and -- unary and funcurry for positive arity constructors, then combine the -- constructors with consts. Example: -- --
-- instance Enumerable a => Enumerable [a] where -- enumerate = consts [unary (funcurry (:)), pure []] ---- -- There's also a handy Template Haskell function for automatic -- derivation. module Test.Feat.Class -- | A class of functionally enumerable types class Typeable a => Enumerable a where shared = tagShare Class enumerate enumerate :: Enumerable a => Enumerate a shared :: Enumerable a => Enumerate a type Constructor = Enumerate -- | For nullary constructors such as True and []. nullary :: a -> Constructor a -- | For any non-nullary constructor. Apply funcurry until the type -- of the result is unary (i.e. n-1 times where n is the number of fields -- of the constructor). unary :: Enumerable a => (a -> b) -> Constructor b -- | Uncurry a function (typically a constructor) to a function on free -- pairs. funcurry :: (a -> b -> c) -> FreePair a b -> c -- | Produces the enumeration of a type given the enumerators for each of -- its constructors. The result of unary should typically not be -- used directly in an instance even if it only has one constructor. So -- you should apply consts even in that case. consts :: [Constructor a] -> Enumerate a -- | An optimised version of enumerate. Used by all library functions that -- access enumerated values (but not by combining functions). Library -- functions should ensure that optimised is not reevaluated. optimised :: Enumerable a => Enumerate a -- | A free pair constructor. The cost of constructing a free pair is equal -- to the sum of the costs of its components. newtype FreePair a b Free :: (a, b) -> FreePair a b free :: FreePair a b -> (a, b) -- | Derive an instance of Enumberable with Template Haskell. deriveEnumerable :: Name -> Q [Dec] instance Typeable Natural instance Show Natural instance Enumerable Char instance Enumerable Float instance Enumerable Double instance Enumerable Int64 instance Enumerable Int32 instance Enumerable Int16 instance Enumerable Int8 instance Enumerable Int instance Enumerable Word64 instance Enumerable Word32 instance Enumerable Word16 instance Enumerable Word8 instance Enumerable Word instance Enumerable Integer instance Enumerable Natural instance Enumerable Ordering instance Enumerable a0 => Enumerable (Maybe a0) instance (Enumerable a0, Enumerable b0) => Enumerable (Either a0 b0) instance (Enumerable a0, Enumerable b0, Enumerable c0, Enumerable d0, Enumerable e0, Enumerable f0, Enumerable g0) => Enumerable (a0, b0, c0, d0, e0, f0, g0) instance (Enumerable a0, Enumerable b0, Enumerable c0, Enumerable d0, Enumerable e0, Enumerable f0) => Enumerable (a0, b0, c0, d0, e0, f0) instance (Enumerable a0, Enumerable b0, Enumerable c0, Enumerable d0, Enumerable e0) => Enumerable (a0, b0, c0, d0, e0) instance (Enumerable a0, Enumerable b0, Enumerable c0, Enumerable d0) => Enumerable (a0, b0, c0, d0) instance (Enumerable a0, Enumerable b0, Enumerable c0) => Enumerable (a0, b0, c0) instance (Enumerable a0, Enumerable b0) => Enumerable (a0, b0) instance Enumerable () instance Enumerable Bool instance Enumerable a0 => Enumerable [a0] instance Typeable2 FreePair instance (Show a, Show b) => Show (FreePair a b) instance (Enumerable a, Enumerable b) => Enumerable (FreePair a b) -- | Types with invariants. Currently these are mostly examples of how to -- define such types, suggestions on useful types are appreciated. -- -- To use the invariant types you can use the record label. For instance: -- --
-- data C a = C [a] [a] deriving Typeable -- instance Enumerable a => Enumerable (C a) where -- enumerate = unary $ funcurry $ -- xs ys -> C (nonEmpty xs) (nonEmpty ys) ---- -- Alternatively you can put everything in pattern postition: -- --
-- instance Enumerable a => Enumerable (C a) where -- enumerate = unary $ funcurry $ -- (Free (NonEmpty xs,NonEmpty ys)) -> C xs ys) ---- -- The first approach has the advantage of being usable with a point free -- style: xs -> C (nonEmpty xs) . nonEmpty . module Test.Feat.Modifiers -- | A type of non empty lists. newtype NonEmpty a NonEmpty :: [a] -> NonEmpty a nonEmpty :: NonEmpty a -> [a] mkNonEmpty :: a -> [a] -> [a] -- | A type of natural numbers. newtype Nat Nat :: Integer -> Nat nat :: Nat -> Integer instance Typeable1 NonEmpty instance Typeable Nat instance Show a => Show (NonEmpty a) instance Show Nat instance Enumerable Nat instance Enumerable a => Enumerable (NonEmpty a) -- | Functions for accessing the values of enumerations including -- compatability with the property based testing frameworks QuickCheck -- and SmallCheck. module Test.Feat.Access -- | Mainly as a proof of concept we can use the isomorphism between -- natural numbers and (Part,Index) pairs to index into a type May not -- terminate for finite types. Might be slow the first time it is used -- with a specific enumeration because cardinalities need to be -- calculated. The computation complexity after cardinalities are -- computed is a polynomial of the size of the resulting value. index :: Enumerate a -> Integer -> a -- | All values of the enumeration by increasing cost (which is the number -- of constructors for most types). Also contains the cardinality of each -- list. values :: Enumerable a => [(Integer, [a])] -- | A generalisation of values that enumerates every nth value of -- the enumeration from a given starting point. As a special case -- values = striped 0 0 1. striped :: Enumerable a => Part -> Index -> Integer -> [(Integer, [a])] -- | A version of vales that has a limited number of values in each inner -- list. If the list corresponds to a Part which is larger than the bound -- it evenly intersperses the values across the enumeration of the Part. bounded :: Enumerable a => Integer -> [(Integer, [a])] -- | A rather simple but general property testing driver. The property is a -- (funcurried) IO function that both tests and reports the error. The -- driver goes on forever or until the list is exhausted, reporting the -- coverage and the number of tests before each new part. ioFeat :: [(Integer, [a])] -> (a -> IO ()) -> IO () -- | ioAll = ioFeat values ioAll :: Enumerable a => (a -> IO ()) -> IO () -- | ioBounded n = ioFeat (bounded n) ioBounded :: Enumerable a => Integer -> (a -> IO ()) -> IO () -- | Compatability with QuickCheck. Distribution is uniform generator over -- values bounded by the given size. Typical use: sized uniform. uniform :: Enumerable a => Int -> Gen a -- | Compatability with SmallCheck. toSeries :: Enumerable a => Int -> [a] -- | Non class version of values. valuesWith :: Enumerate a -> [(Integer, [a])] -- | Non class version of striped. stripedWith :: Enumerate a -> Part -> Index -> Integer -> [(Integer, [a])] -- | Non class version of bounded. boundedWith :: Enumerate a -> Integer -> [(Integer, [a])] -- | Non class version of uniform. uniformWith :: Enumerate a -> Part -> Gen a -- | Non class version of toSeries. toSeriesWith :: Enumerate a -> Int -> [a] module Test.Feat -- | A functional enumeration of type t is a partition of t into finite -- numbered sets called Parts. The number that identifies each part is -- called the cost of the values in that part. data Enumerate a Enumerate :: (Part -> Index) -> (Part -> Index -> a) -> Sharing Tag (Enumerate a) -> Enumerate a -- | Computes the cardinality of a given part. card :: Enumerate a -> Part -> Index -- | Selects a value from the enumeration For select e p i, -- i should be less than card e p select :: Enumerate a -> Part -> Index -> a -- | A self-optimising function. optimal :: Enumerate a -> Sharing Tag (Enumerate a) -- | A class of functionally enumerable types class Typeable a => Enumerable a where shared = tagShare Class enumerate enumerate :: Enumerable a => Enumerate a shared :: Enumerable a => Enumerate a -- | For nullary constructors such as True and []. nullary :: a -> Constructor a -- | For any non-nullary constructor. Apply funcurry until the type -- of the result is unary (i.e. n-1 times where n is the number of fields -- of the constructor). unary :: Enumerable a => (a -> b) -> Constructor b -- | Uncurry a function (typically a constructor) to a function on free -- pairs. funcurry :: (a -> b -> c) -> FreePair a b -> c -- | Produces the enumeration of a type given the enumerators for each of -- its constructors. The result of unary should typically not be -- used directly in an instance even if it only has one constructor. So -- you should apply consts even in that case. consts :: [Constructor a] -> Enumerate a -- | Derive an instance of Enumberable with Template Haskell. deriveEnumerable :: Name -> Q [Dec] -- | A free pair constructor. The cost of constructing a free pair is equal -- to the sum of the costs of its components. newtype FreePair a b Free :: (a, b) -> FreePair a b free :: FreePair a b -> (a, b) -- | An optimised version of enumerate. Used by all library functions that -- access enumerated values (but not by combining functions). Library -- functions should ensure that optimised is not reevaluated. optimised :: Enumerable a => Enumerate a -- | Mainly as a proof of concept we can use the isomorphism between -- natural numbers and (Part,Index) pairs to index into a type May not -- terminate for finite types. Might be slow the first time it is used -- with a specific enumeration because cardinalities need to be -- calculated. The computation complexity after cardinalities are -- computed is a polynomial of the size of the resulting value. index :: Enumerate a -> Integer -> a -- | All values of the enumeration by increasing cost (which is the number -- of constructors for most types). Also contains the cardinality of each -- list. values :: Enumerable a => [(Integer, [a])] -- | A version of vales that has a limited number of values in each inner -- list. If the list corresponds to a Part which is larger than the bound -- it evenly intersperses the values across the enumeration of the Part. bounded :: Enumerable a => Integer -> [(Integer, [a])] -- | Compatability with QuickCheck. Distribution is uniform generator over -- values bounded by the given size. Typical use: sized uniform. uniform :: Enumerable a => Int -> Gen a -- | ioAll = ioFeat values ioAll :: Enumerable a => (a -> IO ()) -> IO () -- | ioBounded n = ioFeat (bounded n) ioBounded :: Enumerable a => Integer -> (a -> IO ()) -> IO ()