-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Testable functions -- -- Generate, shrink, and show functions for testing higher-order -- properties. See README. @package test-fun @version 0.1.0.0 -- | Representation of (higher-order) functions. -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. module Test.Fun.Internal.Types -- | Name of a function. type FunName = String -- | Name of a type. type TypeName = String -- | Name of a constructor. type ConName = String -- | The type of showsPrec. type ShowsPrec r = Int -> r -> String -> String -- | Dictionary with shrinker and printer. Used as part of the -- representation of higher-order functions with -- (:->). data Concrete r Concrete :: (r -> [r]) -> ShowsPrec r -> Concrete r [shrinkC] :: Concrete r -> r -> [r] [showsPrecC] :: Concrete r -> ShowsPrec r -- | Trivial shrinker and default printer. hardConcrete :: Show r => Concrete r -- | Testable representation of functions (a -> r). -- -- This representation supports random generation, shrinking, and -- printing, for property testing with QuickCheck or Hedgehog. -- -- Higher-order functions can be represented. data a :-> r -- | Constant function, ignore the argument. [Const] :: r -> a :-> r -- | Apply the argument (a -> b) to a value a, stored -- in some representation w, and describe what to do with the -- result b in another function. [CoApply] :: Concrete w -> w -> (w -> a) -> (b :-> ((a -> b) :-> r)) -> (a -> b) :-> r -- | Apply some function to the argument a. [Apply] :: FunName -> (a -> b) -> (b :-> r) -> a :-> r -- | Pattern-match on the argument (in some ADT). The branches may be -- incomplete, in which case a default value r is used. [Case] :: TypeName -> (a -> x) -> Branches x r -> r -> a :-> r -- | Pattern-match on the argument (of some integral type). [CaseInteger] :: TypeName -> (a -> Integer) -> Bin r -> r -> a :-> r -- | There is no value for the argument, so we're done. [Absurd] :: (a -> Void) -> a :-> r -- | Marker for truncating infinite representations. [ToShrink] :: (a :-> r) -> a :-> r infixr 1 :-> -- | Representation of the branches of a Case. data Branches x r [Fail] :: Branches x r [Alt] :: !Branches x r -> !Branches y r -> Branches (Either x y) r [Pat] :: ConName -> !Fields x r -> Branches x r -- | Representation of one branch of a Case. data Fields x r [NoField] :: r -> Fields () r [Field] :: !Fields x (y :-> r) -> Fields (x, y) r -- | Representation of branches of a CaseInteger. data Bin r BinEmpty :: Bin r BinAlt :: Maybe r -> Bin r -> Bin r -> Bin r BinToShrink :: Bin r -> Bin r coapply :: Concrete w -> w -> (w -> a) -> (b :-> ((a -> b) :-> r)) -> (a -> b) :-> r apply :: FunName -> (a -> b) -> (b :-> r) -> a :-> r case_ :: TypeName -> (a -> x) -> Branches x r -> r -> a :-> r caseInteger :: TypeName -> (a -> Integer) -> Bin r -> r -> a :-> r alt :: Branches x r -> Branches y r -> Branches (Either x y) r binAlt :: r -> Bin r -> Bin r -> Bin r -- | Evaluate a representation into the function it represents. applyFun :: (a :-> r) -> a -> r -- | Apply a binary function representation. applyFun2 :: (a :-> (b :-> r)) -> a -> b -> r -- | Apply a ternary function representation. applyFun3 :: (a :-> (b :-> (c :-> r))) -> a -> b -> c -> r applyBranches :: r -> Branches x r -> x -> r applyFields :: Fields x r -> x -> r applyBin :: r -> Bin r -> Integer -> r applyBin' :: r -> Bin r -> Integer -> r -- | Remove ToShrink nodes from evaluating a given argument -- a. clearFun :: (r -> r) -> a -> (a :-> r) -> a :-> r clearBranches :: forall x r. (r -> r) -> Branches x r -> x -> Maybe (Branches x r) clearFields :: (r -> r) -> Fields x r -> x -> Fields x r clearBin :: (r -> r) -> Bin r -> Integer -> Maybe (Bin r) clearBin' :: (r -> r) -> Integer -> Bin r -> Maybe (Bin r) truncateFun :: Int -> (r -> t) -> t -> (a :-> r) -> a :-> t truncateBin :: Int -> (r -> s) -> Bin r -> Bin s instance Data.Traversable.Traversable Test.Fun.Internal.Types.Bin instance Data.Foldable.Foldable Test.Fun.Internal.Types.Bin instance GHC.Base.Functor Test.Fun.Internal.Types.Bin instance GHC.Show.Show r => GHC.Show.Show (Test.Fun.Internal.Types.Bin r) instance GHC.Classes.Ord r => GHC.Classes.Ord (Test.Fun.Internal.Types.Bin r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Test.Fun.Internal.Types.Bin r) instance GHC.Base.Functor ((Test.Fun.Internal.Types.:->) a) instance GHC.Base.Functor (Test.Fun.Internal.Types.Branches x) instance GHC.Base.Functor (Test.Fun.Internal.Types.Fields x) instance Data.Foldable.Foldable ((Test.Fun.Internal.Types.:->) a) instance Data.Foldable.Foldable (Test.Fun.Internal.Types.Branches x) instance Data.Foldable.Foldable (Test.Fun.Internal.Types.Fields x) instance Data.Traversable.Traversable ((Test.Fun.Internal.Types.:->) a) instance Data.Traversable.Traversable (Test.Fun.Internal.Types.Branches x) instance Data.Traversable.Traversable (Test.Fun.Internal.Types.Fields x) -- | Shrinker for representation of functions. -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. module Test.Fun.Internal.Shrink -- | Simplify function. shrinkFun :: forall a r. (r -> [r]) -> (a :-> r) -> [a :-> r] shrinkBranches :: forall x r. (r -> [r]) -> Branches x r -> [Branches x r] shrinkFields :: forall x r. (r -> [r]) -> Fields x r -> [Fields x r] shrinkBin :: forall r. (r -> [r]) -> Bin r -> [Bin r] binToShrink :: forall r. Bin r -> Bin r shrinkMaybe :: (r -> [r]) -> Maybe r -> [Maybe r] firstFun :: forall a r t. (r -> Maybe t) -> (a :-> r) -> Maybe t firstBranches :: forall x r t. (r -> Maybe t) -> Branches x r -> Maybe t firstField :: forall x r t. (r -> Maybe t) -> Fields x r -> Maybe t firstBin :: forall r t. (r -> Maybe t) -> Bin r -> Maybe t -- | Pretty printing of function representations. -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. module Test.Fun.Internal.Pretty -- | Prettify function representation. showsPrecFun :: forall a r. ShowsPrec r -> ShowsPrec (a :-> r) -- | Break up lines after braces and indent. -- --

Example

-- -- Input: -- --
--   \x -> case x :: Either _ _ of { Left x1 -> case x1 of { Left x2 -> () ; Right x2 -> case x2 of {} } ; Right x1 -> () }
--   
-- -- Output: -- --
--   \x -> case x :: Either _ _ of {
--     Left x1 -> case x1 of {
--       Left x2 -> () ;
--       Right x2 -> case x2 of {} } ;
--     Right x1 -> () }
--   
indent :: String -> String prettyFun :: forall a r. (r -> C Expr) -> (a :-> r) -> String type DString = String -> String type PrecDString = Int -> DString sid :: DString sstring :: String -> DString (%) :: DString -> DString -> DString infixr 1 % (~%) :: String -> DString -> DString infixr 1 ~% sparens :: Int -> DString -> PrecDString newtype Expr Expr :: PrecDString -> Expr [unExpr] :: Expr -> PrecDString type Pattern = Expr unExpr_ :: Expr -> DString data Var Var :: String -> !Int -> Var data Ctx (:.) :: (Var, Expr) -> Ctx -> Ctx infixr 1 :. defVar :: Var defCtx :: Ctx badCtx :: Ctx -- | Type of values under some context type C a = Ctx -> a eWild :: Pattern eConst :: String -> Expr tConst :: String -> C Expr eInt :: Integer -> Expr eApp :: Expr -> Expr -> Expr tShow :: Show a => a -> C Expr tShow_ :: ShowsPrec a -> a -> C Expr sVar :: Var -> DString eVar :: Var -> Expr addVar :: [Var] -> Ctx -> Ctx -- | Pretty-print a function representation. tFun :: forall a r. (r -> C Expr) -> (a :-> r) -> C Expr tApply :: FunName -> C Expr -> C Expr tCoApply :: Concrete w -> w -> C Expr -> C Expr tAbsurd :: C Expr appendIf :: Semigroup m => Bool -> m -> m -> m -- | True if there is a Fail branch. partialBranches :: Branches x r -> Bool type CBranches = Var -> C [EBranch] data EBranch EBranch :: Pattern -> Expr -> EBranch EBranchEllipsis :: EBranch bEllipsis :: Bin r -> CBranches bWild :: C Expr -> CBranches tCase :: TypeName -> CBranches -> C Expr tBranches :: forall x r. (r -> C Expr) -> Branches x r -> CBranches tFields :: forall x r. (r -> C Expr) -> Fields x r -> ConName -> [Var] -> CBranches nextVar :: Var -> Var mkPattern :: ConName -> [Var] -> Pattern tBin :: (r -> C Expr) -> Bin r -> CBranches data Sign Pos :: Sign Neg :: Sign resign :: Sign -> Integer -> Integer tBin' :: (r -> C Expr) -> Bin r -> C [(Integer, Expr)] ellidedBin :: Bin r -> Bool -- | Show for (:->). -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. module Test.Fun.Internal.Orphan instance GHC.Show.Show r => GHC.Show.Show (a Test.Fun.Internal.Types.:-> r) -- | Random generation of higher-order functions. -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. -- --

Fun fact

-- -- This module only uses an Applicative constraint on the type of -- generators (which is really QuickCheck's Gen). module Test.Fun.Internal.CoGen -- | A "cogenerator" of a is a random generator of functions with -- domain a. They are parameterized by a generator in the -- codomain r. -- -- More generally, we can make cogenerators to generate functions of -- arbitrary arities; Co gen a r is only the type of -- unary cogenerators. -- --
--   gen r -> gen (a :-> r)         -- Co gen a r
--   gen r -> gen (a :-> b :-> r)
--   gen r -> gen (a :-> b :-> c :-> r)
--   gen r -> gen (a :-> b :-> c :-> d :-> r)
--   
--   -- etc.
--   
-- --

More details

-- -- Cogenerators can be composed using id and (.) -- (the usual combinators for functions). The arity of a cogenerator -- f . g is the sum of the arities of f and -- g. -- --
--   id  ::  forall r. gen r -> gen r  -- 0-ary cogenerator
--   
--   -- (1-ary) . (1-ary) = (2-ary)
--   (.) :: (forall r. gen r -> gen (a :-> r)) ->
--          (forall r. gen r -> gen (b :-> r)) ->
--          (forall r. gen r -> gen (a :-> b :-> r))
--   
--   -- (2-ary) . (1-ary) = (3-ary)
--   (.) :: (forall r. gen r -> gen (a :-> b :-> r)) ->
--          (forall r. gen r -> gen (c :-> r)) ->
--          (forall r. gen r -> gen (a :-> b :-> c :-> r))
--   
-- -- Note: the last type parameter r should really be universally -- quantified (as in the above pseudo type signatures), but instead we -- use more specialized types to avoid making types higher-ranked. type Co gen a r = gen r -> gen (a :-> r) -- | Cogenerator for a type a from a cogenerator for b, -- given an embedding function (a -> b), and a name for that -- function (used for pretty-printing). -- --

Example

-- -- The common usage is to construct cogenerators for newtypes. -- --
--   -- Given some cogenerator of Fruit
--   cogenFruit :: Co Gen Fruit r
--   
--   -- Wrap Fruit in a newtype
--   newtype Apple = Apple { unApple :: Fruit }
--   
--   cogenApple :: Co Gen Apple r
--   cogenApple = cogenEmbed "unApple" cogenFruit
--   
-- -- If cogenFruit generates a function that looks like: -- --
--   \y -> case y :: Fruit of { ... }
--   
-- -- then cogenApple will look like this, where y is -- replaced with unApple x: -- --
--   \x -> case unApple x :: Fruit of { ... }
--   
cogenEmbed :: Functor gen => FunName -> (a -> b) -> Co gen b r -> Co gen a r -- | Cogenerator for an integral type. The name of the type is used for -- pretty-printing. -- --

Example

-- --
--   cogenInteger :: Co Gen Integer r
--   cogenInteger = cogenIntegral "Integer"
--   
--   cogenInt :: Co Gen Int r
--   cogenInt = cogenIntegral "Int"
--   
--   cogenWord :: Co Gen Word r
--   cogenWord = cogenIntegral "Word"
--   
cogenIntegral :: (Applicative gen, Integral a) => TypeName -> Co gen a r -- | Variant of cogenIntegral with an explicit conversion to -- Integer. cogenIntegral' :: Applicative gen => TypeName -> (a -> Integer) -> Co gen a r genBin :: Applicative gen => gen r -> gen (Bin r) -- | Extend a cogenerator of functions (a -> b) (i.e., a -- generator of higher-order functions ((a -> b) -> r)), -- applying the function to a given value a and inspecting the -- result with a cogenerator of b. -- -- This is parameterized by a way to generate, shrink, and show values of -- type a or, more generally, some representation a0 of -- values of type a. -- --

Example

-- --
--   -- Assume Chips is some concrete type.
--   concreteChips :: Concrete Chips
--   
--   -- Assume we have a cogenerator of Fish.
--   cogenFish :: forall r. Gen r -> Gen (Fish :-> r)
--   
--   -- Then we can use cogenApply to construct this function
--   -- to transform cogenerators of functions (Chips -> Fish).
--   cogenX :: forall r.
--     Chips ->
--     Gen ((Chips -> Fish) :-> r) ->
--     Gen ((Chips -> Fish) :-> r)
--   cogenX = cogenApply concreteChips id . cogenFish
--   
--   -- If we have some inputs...
--   chips1, chips2, chips3 :: Chips
--   
--   -- ... we can construct a cogenerator of functions by iterating cogenX.
--   cogenF :: forall r. Gen r -> Gen ((Chips -> Fish) :-> r)
--   cogenF = cogenX chips1 . cogenX chips2 . cogenX chips3 . cogenConst
--   
cogenApply :: Functor gen => Concrete a0 -> (a0 -> a) -> a0 -> gen (b :-> ((a -> b) :-> r)) -> gen ((a -> b) :-> r) -- | The trivial cogenerator which generates a constant function. cogenConst :: Functor gen => Co gen a r -- | Construct a cogenerator of functions (a -> b) from a -- cogenerator of b, using gen (Maybe a0) to generate -- random arguments until it returns Nothing. cogenFun :: Monad gen => Concrete a0 -> gen (Maybe a0) -> (a0 -> a) -> Co gen b ((a -> b) :-> r) -> Co gen (a -> b) r -- | Generic cogenerators -- --

Warning

-- -- This is an internal module: it is not subject to any versioning -- policy, breaking changes can happen at any time. It is made available -- only for debugging. Otherwise, use Test.Fun. -- -- If something here seems useful, please open an issue to export it from -- an external module. module Test.Fun.Internal.Generic -- | Implicit, default cogenerator. class Applicative gen => CoArbitrary gen a coarbitrary :: forall r. CoArbitrary gen a => Co gen a r -- | Cogenerator for generic types, parameterized by a list of -- cogenerators, one for each constructor. -- -- The list is constructed with (:+) (pairs) and -- (). -- --

Example

-- --
--   -- Cogenerator for lists, parameterized by a cogenerator for elements.
--   cogenList :: forall a. (forall r. Co Gen a r) -> (forall r. Co Gen [a] r)
--   cogenList coa = cogenGeneric gs where
--     -- gs :: GSumCo Gen [a] r  -- unfolds to --
--     gs ::
--       (gen r -> gen r)                 :+  -- Cogenerator for the empty list
--       (gen r -> gen (a :-> [a] :-> r)) :+  -- Cogenerator for non-empty lists
--       ()
--     gs = id :+ (coa . cogenList coa) :+ ()
--   
cogenGeneric :: forall a r gen. (Generic a, GCoGen a, Applicative gen) => GSumCo gen a r -> Co gen a r -- | Heterogeneous products as nested pairs. These products must be -- terminated by (). -- --
--   a :+ b :+ c :+ ()  -- the product of a, b, c
--   
data a :+ b (:+) :: a -> b -> (:+) a b infixr 2 :+ infixr 2 :+ -- | Cogenerator for lists. -- --

Implementation note

-- -- The cogenerator of a is made monomorphic only to keep the -- type of cogenList at rank 1. But really, don't pay attention to -- the last type argument of Co. -- --
--   cogenList :: ... => Co gen a _ -> Co gen [a] _
--   
cogenList :: forall a r gen. Applicative gen => Co gen a ([a] :-> r) -> Co gen [a] r -- | Class of types with generic cogenerators. class (Typeable_ a, GNormalize (Rep a), GenBranches (Rep a)) => GCoGen a shortTypeName :: forall a. Typeable_ a => TypeName class Typeable_ (a :: k) shortTypeName_ :: Typeable_ a => String -> String -- | Convert a generic Rep into a sum of products made of -- Either and (,), where products are nested to the left -- (i.e., ((((), a), b), c)). type family Normalize (f :: Type -> Type) :: Type -- | Convert a (:*:) product into a left-nested (,) -- product. type family (>*>) (s :: Type) (f :: Type -> Type) :: Type infixl 9 >*> -- | The list of cogenerators for a generic type, one for each constructor. type GSumCo gen a r = GSumCo_ gen (Rep a) r () type family GSumCo_ (gen :: Type -> Type) (f :: Type -> Type) (r :: Type) (t :: Type) :: Type type family (>->) (f :: Type -> Type) (r :: Type) :: Type infixr 9 >-> class GNormalize f gnormalize :: GNormalize f => f p -> Normalize f class GToList f gToList :: GToList f => y -> f p -> y >*> f genBranches :: forall f r gen. (Applicative gen, GenBranches f) => GSumCo_ gen f r () -> gen r -> gen (Branches (Normalize f) r) class GenBranches f genBranches_ :: forall t r y gen. (GenBranches f, Applicative gen) => gen r -> (gen (Branches (Normalize f) r) -> t -> y) -> GSumCo_ gen f r t -> y class MkFields f mkFields :: MkFields f => Fields x (f >-> r) -> Fields (x >*> f) r -- | Generic implementation of coarbitrary. -- --
--   -- Assuming MyData is a data type whose fields are all instances of CoArbitrary.
--   
--   instance CoArbitrary MyData where
--     coarbitrary = coarbitraryGeneric
--   
coarbitraryGeneric :: forall a r gen. (Generic a, GCoArbitrary gen a) => Co gen a r -- | Constraint for coarbitraryGeneric. class (GCoGen a, Applicative gen, GSumCoArb gen (Rep a)) => GCoArbitrary gen a class GSumCoArb gen f gsumCoarb :: forall r t. GSumCoArb gen f => Proxy r -> t -> GSumCo_ gen f r t class GProdCoArb gen f gprodCoarb :: GProdCoArb gen f => gen r -> gen (f >-> r) instance Test.Fun.Internal.Generic.GProdCoArb gen f => Test.Fun.Internal.Generic.GSumCoArb gen (GHC.Generics.M1 GHC.Generics.C c f) instance (Test.Fun.Internal.Generic.GProdCoArb gen f, Test.Fun.Internal.Generic.GProdCoArb gen g) => Test.Fun.Internal.Generic.GProdCoArb gen (f GHC.Generics.:*: g) instance Test.Fun.Internal.Generic.CoArbitrary gen a => Test.Fun.Internal.Generic.GProdCoArb gen (GHC.Generics.M1 GHC.Generics.S c (GHC.Generics.K1 GHC.Generics.R a)) instance Test.Fun.Internal.Generic.GProdCoArb gen GHC.Generics.U1 instance (Test.Fun.Internal.Generic.GCoGen a, GHC.Base.Applicative gen, Test.Fun.Internal.Generic.GSumCoArb gen (GHC.Generics.Rep a)) => Test.Fun.Internal.Generic.GCoArbitrary gen a instance Test.Fun.Internal.Generic.GSumCoArb gen f => Test.Fun.Internal.Generic.GSumCoArb gen (GHC.Generics.M1 GHC.Generics.D c f) instance (Test.Fun.Internal.Generic.GSumCoArb gen f, Test.Fun.Internal.Generic.GSumCoArb gen g) => Test.Fun.Internal.Generic.GSumCoArb gen (f GHC.Generics.:+: g) instance Test.Fun.Internal.Generic.GSumCoArb gen GHC.Generics.V1 instance (GHC.Generics.Constructor c, Test.Fun.Internal.Generic.MkFields f) => Test.Fun.Internal.Generic.GenBranches (GHC.Generics.M1 GHC.Generics.C c f) instance (Test.Fun.Internal.Generic.MkFields f, Test.Fun.Internal.Generic.MkFields g) => Test.Fun.Internal.Generic.MkFields (f GHC.Generics.:*: g) instance Test.Fun.Internal.Generic.MkFields (GHC.Generics.M1 GHC.Generics.S c (GHC.Generics.K1 GHC.Generics.R a)) instance Test.Fun.Internal.Generic.MkFields GHC.Generics.U1 instance (Test.Fun.Internal.Generic.Typeable_ a, Test.Fun.Internal.Generic.GNormalize (GHC.Generics.Rep a), Test.Fun.Internal.Generic.GenBranches (GHC.Generics.Rep a)) => Test.Fun.Internal.Generic.GCoGen a instance Test.Fun.Internal.Generic.GenBranches f => Test.Fun.Internal.Generic.GenBranches (GHC.Generics.M1 GHC.Generics.D c f) instance (Test.Fun.Internal.Generic.GenBranches f, Test.Fun.Internal.Generic.GenBranches g) => Test.Fun.Internal.Generic.GenBranches (f GHC.Generics.:+: g) instance Test.Fun.Internal.Generic.GenBranches GHC.Generics.V1 instance Test.Fun.Internal.Generic.GToList f => Test.Fun.Internal.Generic.GNormalize (GHC.Generics.M1 GHC.Generics.C c f) instance (Test.Fun.Internal.Generic.GToList f, Test.Fun.Internal.Generic.GToList g) => Test.Fun.Internal.Generic.GToList (f GHC.Generics.:*: g) instance Test.Fun.Internal.Generic.GToList (GHC.Generics.M1 GHC.Generics.S c (GHC.Generics.K1 GHC.Generics.R a)) instance Test.Fun.Internal.Generic.GToList GHC.Generics.U1 instance Test.Fun.Internal.Generic.GNormalize f => Test.Fun.Internal.Generic.GNormalize (GHC.Generics.M1 GHC.Generics.D c f) instance (Test.Fun.Internal.Generic.GNormalize f, Test.Fun.Internal.Generic.GNormalize g) => Test.Fun.Internal.Generic.GNormalize (f GHC.Generics.:+: g) instance Test.Fun.Internal.Generic.GNormalize GHC.Generics.V1 instance forall k1 k2 (f :: k1 -> k2) (a :: k1). Test.Fun.Internal.Generic.Typeable_ f => Test.Fun.Internal.Generic.Typeable_ (f a) instance forall k (a :: k). Data.Typeable.Internal.Typeable a => Test.Fun.Internal.Generic.Typeable_ a instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen () instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen Data.Void.Void instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen GHC.Integer.Type.Integer instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen GHC.Types.Int instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen GHC.Types.Word instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen GHC.Types.Bool instance GHC.Base.Applicative gen => Test.Fun.Internal.Generic.CoArbitrary gen GHC.Types.Ordering instance Test.Fun.Internal.Generic.CoArbitrary gen a => Test.Fun.Internal.Generic.CoArbitrary gen [a] instance Test.Fun.Internal.Generic.CoArbitrary gen a => Test.Fun.Internal.Generic.CoArbitrary gen (GHC.Maybe.Maybe a) instance (Test.Fun.Internal.Generic.CoArbitrary gen a, Test.Fun.Internal.Generic.CoArbitrary gen b) => Test.Fun.Internal.Generic.CoArbitrary gen (a, b) instance (Test.Fun.Internal.Generic.CoArbitrary gen a, Test.Fun.Internal.Generic.CoArbitrary gen b) => Test.Fun.Internal.Generic.CoArbitrary gen (Data.Either.Either a b) instance Test.Fun.Internal.Generic.CoArbitrary gen a => Test.Fun.Internal.Generic.CoArbitrary gen (Data.Functor.Identity.Identity a) instance Test.Fun.Internal.Generic.CoArbitrary gen a => Test.Fun.Internal.Generic.CoArbitrary gen (Data.Semigroup.Internal.Sum a) -- | Testable representation of (higher-order) functions. -- -- See the README for an introduction. module Test.Fun -- | Testable representation of functions (a -> r). -- -- This representation supports random generation, shrinking, and -- printing, for property testing with QuickCheck or Hedgehog. -- -- Higher-order functions can be represented. data a :-> r infixr 1 :-> -- | Evaluate a representation into the function it represents. applyFun :: (a :-> r) -> a -> r -- | Apply a binary function representation. applyFun2 :: (a :-> (b :-> r)) -> a -> b -> r -- | Apply a ternary function representation. applyFun3 :: (a :-> (b :-> (c :-> r))) -> a -> b -> c -> r -- | Simplify function. shrinkFun :: forall a r. (r -> [r]) -> (a :-> r) -> [a :-> r] -- | Prettify function representation. showsPrecFun :: forall a r. ShowsPrec r -> ShowsPrec (a :-> r) -- | Break up lines after braces and indent. -- --

Example

-- -- Input: -- --
--   \x -> case x :: Either _ _ of { Left x1 -> case x1 of { Left x2 -> () ; Right x2 -> case x2 of {} } ; Right x1 -> () }
--   
-- -- Output: -- --
--   \x -> case x :: Either _ _ of {
--     Left x1 -> case x1 of {
--       Left x2 -> () ;
--       Right x2 -> case x2 of {} } ;
--     Right x1 -> () }
--   
indent :: String -> String -- | The type of showsPrec. type ShowsPrec r = Int -> r -> String -> String -- | A "cogenerator" of a is a random generator of functions with -- domain a. They are parameterized by a generator in the -- codomain r. -- -- More generally, we can make cogenerators to generate functions of -- arbitrary arities; Co gen a r is only the type of -- unary cogenerators. -- --
--   gen r -> gen (a :-> r)         -- Co gen a r
--   gen r -> gen (a :-> b :-> r)
--   gen r -> gen (a :-> b :-> c :-> r)
--   gen r -> gen (a :-> b :-> c :-> d :-> r)
--   
--   -- etc.
--   
-- --

More details

-- -- Cogenerators can be composed using id and (.) -- (the usual combinators for functions). The arity of a cogenerator -- f . g is the sum of the arities of f and -- g. -- --
--   id  ::  forall r. gen r -> gen r  -- 0-ary cogenerator
--   
--   -- (1-ary) . (1-ary) = (2-ary)
--   (.) :: (forall r. gen r -> gen (a :-> r)) ->
--          (forall r. gen r -> gen (b :-> r)) ->
--          (forall r. gen r -> gen (a :-> b :-> r))
--   
--   -- (2-ary) . (1-ary) = (3-ary)
--   (.) :: (forall r. gen r -> gen (a :-> b :-> r)) ->
--          (forall r. gen r -> gen (c :-> r)) ->
--          (forall r. gen r -> gen (a :-> b :-> c :-> r))
--   
-- -- Note: the last type parameter r should really be universally -- quantified (as in the above pseudo type signatures), but instead we -- use more specialized types to avoid making types higher-ranked. type Co gen a r = gen r -> gen (a :-> r) -- | Cogenerator for a type a from a cogenerator for b, -- given an embedding function (a -> b), and a name for that -- function (used for pretty-printing). -- --

Example

-- -- The common usage is to construct cogenerators for newtypes. -- --
--   -- Given some cogenerator of Fruit
--   cogenFruit :: Co Gen Fruit r
--   
--   -- Wrap Fruit in a newtype
--   newtype Apple = Apple { unApple :: Fruit }
--   
--   cogenApple :: Co Gen Apple r
--   cogenApple = cogenEmbed "unApple" cogenFruit
--   
-- -- If cogenFruit generates a function that looks like: -- --
--   \y -> case y :: Fruit of { ... }
--   
-- -- then cogenApple will look like this, where y is -- replaced with unApple x: -- --
--   \x -> case unApple x :: Fruit of { ... }
--   
cogenEmbed :: Functor gen => FunName -> (a -> b) -> Co gen b r -> Co gen a r -- | Cogenerator for an integral type. The name of the type is used for -- pretty-printing. -- --

Example

-- --
--   cogenInteger :: Co Gen Integer r
--   cogenInteger = cogenIntegral "Integer"
--   
--   cogenInt :: Co Gen Int r
--   cogenInt = cogenIntegral "Int"
--   
--   cogenWord :: Co Gen Word r
--   cogenWord = cogenIntegral "Word"
--   
cogenIntegral :: (Applicative gen, Integral a) => TypeName -> Co gen a r -- | Variant of cogenIntegral with an explicit conversion to -- Integer. cogenIntegral' :: Applicative gen => TypeName -> (a -> Integer) -> Co gen a r -- | Construct a cogenerator of functions (a -> b) from a -- cogenerator of b, using gen (Maybe a0) to generate -- random arguments until it returns Nothing. cogenFun :: Monad gen => Concrete a0 -> gen (Maybe a0) -> (a0 -> a) -> Co gen b ((a -> b) :-> r) -> Co gen (a -> b) r -- | Dictionary with shrinker and printer. Used as part of the -- representation of higher-order functions with -- (:->). data Concrete r Concrete :: (r -> [r]) -> ShowsPrec r -> Concrete r [shrinkC] :: Concrete r -> r -> [r] [showsPrecC] :: Concrete r -> ShowsPrec r -- | Name of a function. type FunName = String -- | Name of a type. type TypeName = String -- | Cogenerator for generic types, parameterized by a list of -- cogenerators, one for each constructor. -- -- The list is constructed with (:+) (pairs) and -- (). -- --

Example

-- --
--   -- Cogenerator for lists, parameterized by a cogenerator for elements.
--   cogenList :: forall a. (forall r. Co Gen a r) -> (forall r. Co Gen [a] r)
--   cogenList coa = cogenGeneric gs where
--     -- gs :: GSumCo Gen [a] r  -- unfolds to --
--     gs ::
--       (gen r -> gen r)                 :+  -- Cogenerator for the empty list
--       (gen r -> gen (a :-> [a] :-> r)) :+  -- Cogenerator for non-empty lists
--       ()
--     gs = id :+ (coa . cogenList coa) :+ ()
--   
cogenGeneric :: forall a r gen. (Generic a, GCoGen a, Applicative gen) => GSumCo gen a r -> Co gen a r -- | Heterogeneous products as nested pairs. These products must be -- terminated by (). -- --
--   a :+ b :+ c :+ ()  -- the product of a, b, c
--   
data a :+ b (:+) :: a -> b -> (:+) a b infixr 2 :+ infixr 2 :+ -- | Cogenerator for lists. -- --

Implementation note

-- -- The cogenerator of a is made monomorphic only to keep the -- type of cogenList at rank 1. But really, don't pay attention to -- the last type argument of Co. -- --
--   cogenList :: ... => Co gen a _ -> Co gen [a] _
--   
cogenList :: forall a r gen. Applicative gen => Co gen a ([a] :-> r) -> Co gen [a] r -- | The trivial cogenerator which generates a constant function. cogenConst :: Functor gen => Co gen a r -- | Extend a cogenerator of functions (a -> b) (i.e., a -- generator of higher-order functions ((a -> b) -> r)), -- applying the function to a given value a and inspecting the -- result with a cogenerator of b. -- -- This is parameterized by a way to generate, shrink, and show values of -- type a or, more generally, some representation a0 of -- values of type a. -- --

Example

-- --
--   -- Assume Chips is some concrete type.
--   concreteChips :: Concrete Chips
--   
--   -- Assume we have a cogenerator of Fish.
--   cogenFish :: forall r. Gen r -> Gen (Fish :-> r)
--   
--   -- Then we can use cogenApply to construct this function
--   -- to transform cogenerators of functions (Chips -> Fish).
--   cogenX :: forall r.
--     Chips ->
--     Gen ((Chips -> Fish) :-> r) ->
--     Gen ((Chips -> Fish) :-> r)
--   cogenX = cogenApply concreteChips id . cogenFish
--   
--   -- If we have some inputs...
--   chips1, chips2, chips3 :: Chips
--   
--   -- ... we can construct a cogenerator of functions by iterating cogenX.
--   cogenF :: forall r. Gen r -> Gen ((Chips -> Fish) :-> r)
--   cogenF = cogenX chips1 . cogenX chips2 . cogenX chips3 . cogenConst
--   
cogenApply :: Functor gen => Concrete a0 -> (a0 -> a) -> a0 -> gen (b :-> ((a -> b) :-> r)) -> gen ((a -> b) :-> r) -- | Implicit, default cogenerator. class Applicative gen => CoArbitrary gen a coarbitrary :: forall r. CoArbitrary gen a => Co gen a r -- | Generic implementation of coarbitrary. -- --
--   -- Assuming MyData is a data type whose fields are all instances of CoArbitrary.
--   
--   instance CoArbitrary MyData where
--     coarbitrary = coarbitraryGeneric
--   
coarbitraryGeneric :: forall a r gen. (Generic a, GCoArbitrary gen a) => Co gen a r -- | Class of types with generic cogenerators. class (Typeable_ a, GNormalize (Rep a), GenBranches (Rep a)) => GCoGen a -- | Constraint for coarbitraryGeneric. class (GCoGen a, Applicative gen, GSumCoArb gen (Rep a)) => GCoArbitrary gen a -- | The list of cogenerators for a generic type, one for each constructor. type GSumCo gen a r = GSumCo_ gen (Rep a) r ()