-- 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 are two (somewhat -- similar) large scale example in the tar ball: testing the Template -- Haskell pretty printer and testing haskell-src-exts. @package testing-feat @version 0.2 -- | 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 for 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, the -- index i should be less than card e p select :: Enumerate a -> Part -> Index -> a -- | A self-optimising function (mainly for internal use). optimal :: Enumerate a -> Sharing Tag (Enumerate a) -- | Disjoint union union :: Enumerate a -> Enumerate a -> Enumerate a -- | The definition of pure for the applicative instance. singleton :: a -> Enumerate a -- | Increases the cost of all values in an enumeration by one. pay :: Enumerate a -> Enumerate a mem :: Enumerate a -> Enumerate a -- | A convenient 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] -- | Derive an instance of Enumberable with Template Haskell, with rules -- for some specific constructors deriveEnumerable' :: ConstructorDeriv -> Q [Dec] type ConstructorDeriv = (Name, [(Name, ExpQ)]) dAll :: Name -> ConstructorDeriv dExcluding :: Name -> ConstructorDeriv -> ConstructorDeriv dExcept :: Name -> ExpQ -> ConstructorDeriv -> ConstructorDeriv instance Enumerable Char instance (Infinite a, Enumerable a) => Enumerable (Ratio a) 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 (Infinite a, Enumerable a) => Enumerable (NonZero a) instance Enumerable Integer instance Infinite a => Enumerable (Nat a) 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) -- | Modifiers for types, i.e. newtype wrappers where the values satisfy -- some constraint (non-empty, positive etc.). Suggestions on useful -- types are appreciated. -- -- To apply the modifiers 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]) -> NonEmpty a -- | A class of infinite precision integral types. Integer is the -- principal class member. class (Typeable a, Integral a) => Infinite a -- | A type of (infinite precision) natural numbers such that nat a -- >= 0 . newtype Nat a Nat :: a -> Nat a nat :: Nat a -> a -- | A type of (infinite precision) non-zero integers such that -- nonZero a /= 0 . newtype NonZero a NonZero :: a -> NonZero a nonZero :: NonZero a -> a -- | Any unicode character. newtype Unicode Unicode :: Char -> Unicode unicode :: Unicode -> Char -- | Smart constructor for unicode strings. unicodes :: [Unicode] -> String -- | Printable ASCII characters newtype Printable Printable :: Char -> Printable printable :: Printable -> Char -- | Smart constructor for printable ASCII strings printables :: [Printable] -> String instance Typeable1 NonEmpty instance Typeable Unicode instance Typeable Printable instance Show a => Show (NonEmpty a) instance Show Unicode instance Eq Unicode instance Ord Unicode instance Show Printable instance Enumerable Printable instance Enumerable Unicode instance Enumerable a => Enumerable (NonEmpty a) -- | Anexperimental feature to override the Enumerable instance for -- any type. module Test.Feat.Class.Override type Override = DynMap Tag noOverride :: Override addOverride :: Enumerable a => Enumerate a -> Override -> Override -- | This function is best described with an example: -- --
-- let e1 = override $ addOverride (unary printable) noOverride :: Enumerate T ---- -- e1 enumerates values of type T where all characters -- (accessed using the Enumerable instance for Char) -- are printable. Sometimes this can save you from placing lots of -- printable modifiers in your instances or newtypes in your data -- type definitions. -- -- This works for any type (not just characters) as long as the instance -- does not override the default definition of shared so it does -- not use tagShare (no instance in the library does this).This -- function should not be used for defining instances (doing so might -- increase memory usage). override :: Enumerable a => Override -> Enumerate a -- | Functions for accessing the values of enumerations including -- compatibility 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 computational complexity (after cardinalities are -- computed) is a polynomial in 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 -- an (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 () -- | Defined as ioAll = ioFeat values ioAll :: Enumerable a => (a -> IO ()) -> IO () -- | Defined as ioBounded n = ioFeat (bounded n) ioBounded :: Enumerable a => Integer -> (a -> IO ()) -> IO () -- | Compatibility with QuickCheck. Distribution is uniform generator over -- values bounded by the given size. Typical use: sized uniform. uniform :: Enumerable a => Int -> Gen a -- | Compatibility 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] -- | This module contains a (hopefully) manageable subset of the -- functionality of Feat. The rest resides only in the Test.Feat.* -- modules. 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, the -- index i should be less than card e p select :: Enumerate a -> Part -> Index -> a -- | A self-optimising function (mainly for internal use). 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 computational complexity (after cardinalities are -- computed) is a polynomial in 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])] -- | Compatibility with QuickCheck. Distribution is uniform generator over -- values bounded by the given size. Typical use: sized uniform. uniform :: Enumerable a => Int -> Gen a -- | A rather simple but general property testing driver. The property is -- an (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 () -- | Defined as ioAll = ioFeat values ioAll :: Enumerable a => (a -> IO ()) -> IO () -- | Defined as ioBounded n = ioFeat (bounded n) ioBounded :: Enumerable a => Integer -> (a -> IO ()) -> IO ()