-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Extensible and Modular Generics for the Masses -- -- EMGM is a general-purpose library for generic programming with type -- classes. -- -- The design is based on the idea of modeling algebraic datatypes as -- sum-of-product structures. Many datatypes can be modeled this way, and -- because they all share a common structure, we can write generic -- functions that work on this structure. -- -- The library provides three main components: -- --
    --
  1. Common - A common foundation for building generic -- functions and adding support for datatypes. This includes the -- collection of datatypes (e.g. sum, product, unit) and type classes -- (e.g. Generic, Rep), that are used throughout the -- library. This is what you need to define your own generic functions, -- to add generic support for your datatype, or to define ad-hoc -- cases.
  2. --
  3. Data - Support for using standard datatypes -- generically. Types such as [a], tuples, and -- Maybe are built into Haskell or come included in the standard -- libraries. EMGM provides full support for generic functions on these -- datatypes. The modules in this component are also useful as guides -- when adding generic support for your own datatypes.
  4. --
  5. Functions - A collection of useful generic -- functions. These work with a variety of datatypes and provide a -- wide range of operations. For example, there is crush, a -- generalization of the fold functions. It is one of the most useful -- functions, because it allows you to flexibly extract the elements of a -- polymorphic container.
  6. --
-- -- For more information on the EMGM library, see the homepage: -- http://www.cs.uu.nl/wiki/GenericProgramming/EMGM @package emgm @version 0.2 -- | Summary: Types and related functions for the representation used in -- EMGM. -- -- EMGM uses a generic sum-of-products view of datatypes encoded into the -- Unit, :+: (sum), and :*: (product). Many -- Haskell datatypes can be represented in this way. Right-nested sums -- replace the |, and right-nested products replace the -- arguments to a constructor. Units replace constructors with no -- arguments. -- -- Since constructors encode more than just a list of arguments, this -- library uses ConDescr to store that information. This includes -- name, arity, record labels, fixity, and operator precedence. -- Constructor descriptions are useful for generic operations such as -- Read and Show and possibly others. -- -- Generic functions need to convert values between the Haskell datatype -- and its structure representation. This is done using the -- embedding-projection pair, which is simply a pair a functions for -- translating between two types. module Generics.EMGM.Common.Representation -- | The "unit" encodes a constructor with no arguments. An analogous -- standard Haskell type is (). data Unit -- | The only value of type Unit (ignoring _|_). Unit :: Unit -- | The "sum" encodes 2 constructor alternatives. An analogous standard -- Haskell type is Either a b. data (:+:) a b -- | Left alternative L :: a -> :+: a b -- | Right alternative R :: b -> :+: a b -- | The "product" encodes 2 constructor arguments. An analogous standard -- Haskell type is (a, b). data (:*:) a b -- | A pair of arguments (:*:) :: a -> b -> :*: a b -- | The embedding-projection pair contains two functions for converting -- between the datatype and its representation. An EP value -- preserves an isomorphism (ignoring _|_s) between a datatype -- and its structure representation. data EP d r EP :: (d -> r) -> (r -> d) -> EP d r -- | Embed a datatype into its representation. from :: EP d r -> (d -> r) -- | Project datatype from its representation. to :: EP d r -> (r -> d) -- | A constructor description containing useful meta-information about the -- syntax used in the data declaration. This is particularly useful in -- Read and Show but may also be helpful in other generic -- functions. -- -- NOTE: It is important that the ConDescr value accurately -- describe the syntax in a constructor declaration. An incorrect -- description may lead to faulty Read or Show operation. data ConDescr ConDescr :: String -> Int -> [String] -> Fixity -> ConDescr -- | Name of the constructor. If it is infix, don't provide parentheses. conName :: ConDescr -> String -- | Arity or number of arguments. conArity :: ConDescr -> Int -- | A list of labels used in record syntax. They must be declared in the -- same order as the data declaration. The list should be empty -- if the constructor is not a record. conLabels :: ConDescr -> [String] -- | Infix or not, associativity, precedence. conFixity :: ConDescr -> Fixity -- | The constructor type used in Read and Show to determine -- how to parse or print the constructor. data ConType -- | Standard (function-type, nonfix) ConStd :: ConType -- | Record-style (nonfix or infix) ConRec :: [String] -> ConType -- | Infix (no record syntax) ConIfx :: String -> ConType -- | An identifier's fixity, associativity, and precedence. If not infix -- (Nonfix), the associativity and precedence of the identifier is -- the same as function application. If infix, the associativity is -- indicated by the constructor and the precedence is an argument to it. data Fixity -- | Not infix. Associativity and precedence are the same as function -- application. Nonfix :: Fixity -- | Non-associative infix with precedence. Infix :: Prec -> Fixity -- | Left-associative infix with precedence. Infixl :: Prec -> Fixity -- | Right-associative Infix with precedence. Infixr :: Prec -> Fixity -- | Get the precedence of a fixity value. prec :: Fixity -> Prec -- | Maximum precedence: 11 maxPrec :: Prec -- | Precedence for function application: 10 appPrec :: Prec -- | Precedence for record construction: 11 recPrec :: Prec instance Eq Fixity instance Show Fixity instance Eq ConType instance Show ConType instance Eq ConDescr instance Show ConDescr instance (Eq a, Eq b) => Eq (a :*: b) instance (Ord a, Ord b) => Ord (a :*: b) instance (Read a, Read b) => Read (a :*: b) instance (Show a, Show b) => Show (a :*: b) instance (Eq a, Eq b) => Eq (a :+: b) instance (Ord a, Ord b) => Ord (a :+: b) instance (Read a, Read b) => Read (a :+: b) instance (Show a, Show b) => Show (a :+: b) instance Enum Unit instance Eq Unit instance Ord Unit instance Show Unit instance Read Unit -- | Summary: Type classes used for generic functions with one -- generic argument. -- -- Generic functions using one generic argument are defined as instances -- of Generic. This class contains all of the methods (called -- "type cases" in datatype-generic language) used to define the run-time -- type representation of a datatype. -- -- To simplify generic functions, we use type classes for representation -- dispatching. There are "dispatchers" for each category of function -- (see below) and each category has one "Rep" class. -- -- Some Generic-based functions operate on monomorphic values -- (using Rep). The functions included with the library are: -- -- -- -- Other Generic-based functions operate on types of the form -- f a (using FRep) where f is the actual -- generic argument (the one that needs a run-time representation). The -- functions included with the library are: -- -- module Generics.EMGM.Common.Base -- | This class forms the foundation for defining generic functions with a -- single generic argument. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic g rconstant :: (Generic g, Enum a, Eq a, Ord a, Read a, Show a) => g a rint :: (Generic g) => g Int rinteger :: (Generic g) => g Integer rfloat :: (Generic g) => g Float rdouble :: (Generic g) => g Double rchar :: (Generic g) => g Char runit :: (Generic g) => g Unit rsum :: (Generic g) => g a -> g b -> g (a :+: b) rprod :: (Generic g) => g a -> g b -> g (a :*: b) rcon :: (Generic g) => ConDescr -> g a -> g a rtype :: (Generic g) => EP b a -> g a -> g b -- | The Generic representation dispatcher for monomorphic types -- (kind *). Every structure type and supported datatype should -- have an instance of Rep. (No default implementation.) class Rep g a rep :: (Rep g a) => g a -- | The Generic representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep g f frep :: (FRep g f) => g a -> g (f a) instance [overlap ok] (Generic g, Rep g a, Rep g b) => Rep g (a :*: b) instance [overlap ok] (Generic g, Rep g a, Rep g b) => Rep g (a :+: b) instance [overlap ok] (Generic g) => Rep g Unit instance [overlap ok] (Generic g) => Rep g Char instance [overlap ok] (Generic g) => Rep g Double instance [overlap ok] (Generic g) => Rep g Float instance [overlap ok] (Generic g) => Rep g Integer instance [overlap ok] (Generic g) => Rep g Int -- | Summary: Type classes used for generic functions with two -- generic arguments. -- -- Generic functions using two generic arguments are defined as instances -- of Generic2. This class contains all of the methods (called -- "type cases" in datatype-generic language) used to define the run-time -- type representation of a datatype. -- -- Generic2-based functions have a representation dispatcher type -- class FRep2. -- -- The functions included with the library are: -- -- module Generics.EMGM.Common.Base2 -- | This class forms the foundation for defining generic functions with -- two generic arguments. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic2 g rconstant2 :: (Generic2 g, Enum a, Eq a, Ord a, Read a, Show a) => g a a rint2 :: (Generic2 g) => g Int Int rinteger2 :: (Generic2 g) => g Integer Integer rfloat2 :: (Generic2 g) => g Float Float rdouble2 :: (Generic2 g) => g Double Double rchar2 :: (Generic2 g) => g Char Char runit2 :: (Generic2 g) => g Unit Unit rsum2 :: (Generic2 g) => g a1 a2 -> g b1 b2 -> g (a1 :+: b1) (a2 :+: b2) rprod2 :: (Generic2 g) => g a1 a2 -> g b1 b2 -> g (a1 :*: b1) (a2 :*: b2) rcon2 :: (Generic2 g) => ConDescr -> g a1 a2 -> g a1 a2 rtype2 :: (Generic2 g) => EP a2 a1 -> EP b2 b1 -> g a1 b1 -> g a2 b2 -- | The Generic2 representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep2 g f frep2 :: (FRep2 g f) => g a b -> g (f a) (f b) -- | The Generic2 representation dispatcher for bifunctor types -- (kind * -> * -> *). (No default implementation.) class BiFRep2 g f bifrep2 :: (BiFRep2 g f) => g a1 b1 -> g a2 b2 -> g (f a1 a2) (f b1 b2) -- | Summary: Type classes used for generic functions with three -- generic arguments. -- -- Generic functions using three generic arguments are defined as -- instances of Generic3. This class contains all of the methods -- (called "type cases" in datatype-generic language) used to define the -- run-time type representation of a datatype. -- -- Generic3-based functions have a non-extensible representation -- dispatcher type class, FRep3. -- -- The functions included with the library are: -- -- module Generics.EMGM.Common.Base3 -- | This class forms the foundation for defining generic functions with -- three generic arguments. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic3 g rconstant3 :: (Generic3 g, Enum a, Eq a, Ord a, Read a, Show a) => g a a a rint3 :: (Generic3 g) => g Int Int Int rinteger3 :: (Generic3 g) => g Integer Integer Integer rfloat3 :: (Generic3 g) => g Float Float Float rdouble3 :: (Generic3 g) => g Double Double Double rchar3 :: (Generic3 g) => g Char Char Char runit3 :: (Generic3 g) => g Unit Unit Unit rsum3 :: (Generic3 g) => g a1 a2 a3 -> g b1 b2 b3 -> g (a1 :+: b1) (a2 :+: b2) (a3 :+: b3) rprod3 :: (Generic3 g) => g a1 a2 a3 -> g b1 b2 b3 -> g (a1 :*: b1) (a2 :*: b2) (a3 :*: b3) rcon3 :: (Generic3 g) => ConDescr -> g a1 a2 a3 -> g a1 a2 a3 rtype3 :: (Generic3 g) => EP a2 a1 -> EP b2 b1 -> EP c2 c1 -> g a1 b1 c1 -> g a2 b2 c2 -- | The Generic3 representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep3 g f frep3 :: (FRep3 g f) => g a b c -> g (f a) (f b) (f c) -- | Summary: Generic function that collects all values of a specified type -- from a generic value. module Generics.EMGM.Functions.Collect -- | The type of a generic function that takes a value of one type and -- returns a list of values of another type. -- -- For datatypes to work with Collect, a special instance must be given. -- This instance is trivial to write. Given a type D, the -- Rep instance looks like this: -- --
--   {-# LANGUAGE OverlappingInstances #-}
--   
--   data D = ...
--   
--   instance Rep (Collect D) D where
--     rep = Collect (:[])
--   
-- -- (Note the requirement of overlapping instances.) This instance -- triggers when the result type (the first D) matches some -- value type (the second D) contained within the argument to -- collect. See the source of this module for more examples. newtype Collect b a Collect :: (a -> [b]) -> Collect b a selCollect :: Collect b a -> a -> [b] -- | Collect values of type b from some value of type a. -- An empty list means no values were collected. If you expected -- otherwise, be sure that you have an instance such as Rep -- (Collect B) B for the type B that you are -- collecting. -- -- collect works by searching a datatype for values that are the -- same type as the return type specified. Here are some examples using -- the same value but different return types: -- --
--   ghci> let x = [Left 1, Right a, Left 2] :: [Either Int Char]
--   ghci> collect x :: [Int]
--   [1,2]
--   ghci> collect x :: [Char]
--   "a"
--   ghci> collect x == x
--   True
--   
-- -- Note that the numerical constants have been declared Int -- using the type annotation. Since these natively have the type Num -- a => a, you may need to give explicit types. By design, there -- is no connection that can be inferred between the return type and the -- argument type. -- -- collect only works if there is an instance for the return -- type as described in the newtype Collect. collect :: (Rep (Collect b) a) => a -> [b] instance [overlap ok] Rep (Collect Char) Char instance [overlap ok] Rep (Collect Double) Double instance [overlap ok] Rep (Collect Float) Float instance [overlap ok] Rep (Collect Integer) Integer instance [overlap ok] Rep (Collect Int) Int instance [overlap ok] Generic (Collect b) -- | Summary: Functions for generating support for using a datatype with -- EMGM. -- -- Generating datatype support can be done in a fully automatic way using -- derive or deriveWith, or it can be done piecemeal using -- a number of other functions. For most needs, the automatic approach is -- fine. But if you find you need more control, use the manual deriving -- approach described here. module Generics.EMGM.Common.Derive -- | Derive all appropriate instances for using EMGM with a datatype. -- -- Here is an example module that shows how to use derive: -- --
--   {-# LANGUAGE TemplateHaskell       #-}
--   {-# LANGUAGE MultiParamTypeClasses #-}
--   {-# LANGUAGE FlexibleContexts      #-}
--   {-# LANGUAGE FlexibleInstances     #-}
--   {-# LANGUAGE OverlappingInstances  #-}
--   {-# LANGUAGE UndecidableInstances  #-}
--   
-- --
--   module Example where
--   import Generics.EMGM
--   data T a = C a Int
--   
-- --
--   $(derive ''T)
--   
-- -- The Template Haskell derive declaration in the above example -- generates the following (annotated) code: -- --
--   -- (1) Constructor description declarations (1 per constructor)
--   
-- --
--   conC :: ConDescr
--   conC = ConDescr "C" 2 [] Nonfix
--   
-- --
--   -- (2) Embedding-projection pair declarations (1 per type)
--   
-- --
--   epT :: EP (T a) (a :*: Int)
--   epT = EP fromT toT
--     where fromT (C v1 v2) = v1 :*: v2
--           toT (v1 :*: v2) = C v1 v2
--   
-- --
--   -- (3) Rep instance (1 per type)
--   
-- --
--   instance (Generic g, Rep g a, Rep g Int) => Rep g (T a) where
--     rep = rtype epT (rcon conC (rprod rep rep))
--   
-- --
--   -- (4) Higher arity instances if applicable (either FRep, FRep2, and
--   -- FRep3 together, or BiFRep2)
--   
-- --
--   instance (Generic g) => FRep g T where
--     frep ra = rtype epT (rcon conC (rprod ra rint))
--   
-- --
--   -- In this case, similar instances would be generated for FRep2 and FRep3.
--   
-- --
--   -- (5) Function-specific instances (1 per type)
--   
-- --
--   instance Rep (Collect Char) Char where
--     rep = Collect (:[])
--   
-- -- Note that the constructor description conC and -- embedding-project pair epT are top-level values. This allows -- them to be shared between multiple instances. If these names conflict -- with your own, you may want to put the $(derive ...) -- declaration in its own module and restrict the export list. derive :: Name -> Q [Dec] -- | Same as derive except that you can pass a list of name -- modifications to the deriving mechanism. -- -- Use deriveWith if: -- --
    --
  1. You want to use the generated constructor descriptions or -- embedding-projection pairs and one of your constructors or -- types is an infix symbol. In other words, if you have a constructor -- :*, you cannot refer to the (invalid) generated name for its -- description, con:*. It appears that GHC has no problem with -- that name internally, so this is only if you want access to it.
  2. --
  3. You want to define your own constructor description. This allows -- you to give a precise implementation different from the one generated -- for you.
  4. --
-- -- For option 1, use ChangeTo as in this example: -- --
--   data U = Int :* Char
--   $(deriveWith [(":*", ChangeTo "Star")] ''U)
--   x = ... conStar ...
--   
-- -- For option 2, use DefinedAs as in this example: -- --
--   data V = (:=) { i :: Int, j :: Char }
--   $(deriveWith [(":=", DefinedAs "Equals")] ''V)
--   conEquals = ConDescr ":=" 2 [] (Infix 4)
--   
-- -- Using the example for option 2 with -- Generics.EMGM.Functions.Show will print values of V as -- infix instead of the default record syntax. -- -- Note that only the first pair with its first field matching the type -- or constructor name in the Modifiers list will be used. Any -- other matches will be ignored. deriveWith :: Modifiers -> Name -> Q [Dec] -- | Modify the action taken for a given name. data Modifier -- | Change the syntactic name (of a type or constructor) to the argument -- in the generated EP or ConDescr value. This results in a value named -- epX or conX if the argument is "X". ChangeTo :: String -> Modifier -- | Use this for the name of a user-defined constructor description -- instead of a generated one. The generated code assumes the existance -- of conX :: ConDescr (in scope) if the argument is -- "X". DefinedAs :: String -> Modifier -- | List of pairs mapping a (type or constructor) name to a modifier -- action. type Modifiers = [(String, Modifier)] -- | Generate declarations of ConDescr values for all constructors -- in a type. See derive for an example. declareConDescrs :: Name -> Q [Dec] -- | Same as declareConDescrs except that you can pass a list of -- name modifications to the deriving mechanism. See deriveWith -- for an example. declareConDescrsWith :: Modifiers -> Name -> Q [Dec] -- | Generate declarations of EP values for a type. See -- derive for an example. declareEP :: Name -> Q [Dec] -- | Same as declareEP except that you can pass a list of name -- modifications to the deriving mechanism. See deriveWith for an -- example. declareEPWith :: Modifiers -> Name -> Q [Dec] -- | Generate Rep instance declarations for a type. See -- derive for an example. deriveRep :: Name -> Q [Dec] -- | Same as deriveRep except that you can pass a list of name -- modifications to the deriving mechanism. See deriveWith for an -- example. deriveRepWith :: Modifiers -> Name -> Q [Dec] -- | Generate FRep, FRep2, and FRep3 instance -- declarations for a type. See derive for an example. deriveFRep :: Name -> Q [Dec] -- | Same as deriveFRep except that you can pass a list of name -- modifications to the deriving mechanism. See deriveWith for an -- example. deriveFRepWith :: Modifiers -> Name -> Q [Dec] -- | Generate BiFRep2 instance declarations for a type. See -- derive for an example. deriveBiFRep :: Name -> Q [Dec] -- | Same as deriveBiFRep except that you can pass a list of name -- modifications to the deriving mechanism. See deriveWith for an -- example. deriveBiFRepWith :: Modifiers -> Name -> Q [Dec] -- | Generate a Rep Collect T instance declaration -- for a type T. See derive for an example. deriveCollect :: Name -> Q [Dec] -- | Exports all modules in the Generics.EMGM.Common.* hierarchy. module Generics.EMGM.Common -- | Summary: Generic functions for comparing two values in different ways. -- -- The fundamental function here is compare, a function that -- returns the Ordering of two values (less than, equal to, or -- greater than). It uses the same lexicographical ordering as -- deriving Ord (e.g. left alternative of a sum is less than the -- right alternative, the first component of a product is compared first -- while the second is only compared if the first is equal, etc.). -- -- All of the remaining functions are simply derived (in the most obvious -- way) from compare. All of these functions are equivalent to -- methods in the Eq and Ord type classes. The difference -- with using this approach vs. deriving (Eq, Ord) is that you -- can write ad-hoc cases for certain datatypes while most of the -- functionality is handled generically. module Generics.EMGM.Functions.Compare -- | The type of a generic function that takes two values of the same type -- and returns an Ordering. newtype Compare a Compare :: (a -> a -> Ordering) -> Compare a selCompare :: Compare a -> a -> a -> Ordering -- | Compare two values and return an Ordering (i.e. LT, -- GT, or EQ). This is implemented exactly as if the -- datatype was deriving Ord. compare :: (Rep Compare a) => a -> a -> Ordering -- | Equal to. Returns x == y. eq :: (Rep Compare a) => a -> a -> Bool -- | Not equal to. Returns x /= y. neq :: (Rep Compare a) => a -> a -> Bool -- | Less than. Returns x < y. lt :: (Rep Compare a) => a -> a -> Bool -- | Less than or equal to. Returns x <= y. lteq :: (Rep Compare a) => a -> a -> Bool -- | Greater than. Returns x > y. gt :: (Rep Compare a) => a -> a -> Bool -- | Greater than or equal to. Returns x >= y. gteq :: (Rep Compare a) => a -> a -> Bool -- | The minimum of two values. min :: (Rep Compare a) => a -> a -> a -- | The maximum of two values. max :: (Rep Compare a) => a -> a -> a instance Generic Compare -- | Summary: Generic functions that crush a container into an iteration -- over its elements. -- -- Crush is a datatype-generic operation on container types. It is a -- generalization of folds, but it is not a catamorphism. To understand -- how crush works, one can think of it as generating a list of all -- elements and mapping an accumulating function over each one. With this -- image in mind, it is evident that (unlike a catamorphism) very little -- information can be determined about the structure of the container. -- -- The EMGM implementation of crush can not inherently know the -- associativity of the binary operator. Consequently, associativity is -- left as an argument, but there are variants specific to left- and -- right-associativity for convenience. -- -- Many standard Haskell datatypes (e.g. [], Data.Tree) -- are designed such that a constructor with more than one argument (i.e. -- a product structurally represented by (:*:)) has the element -- on the left and any recursive points towards the right. Due to this, -- the right-associative functions would typically produce the expected -- values. See examples in the comments for flattenr and -- firstr. module Generics.EMGM.Functions.Crush -- | The type of a generic function that takes an associativity and two -- arguments of different types and returns a value of the type of the -- second. newtype Crush b a Crush :: (Assoc -> a -> b -> b) -> Crush b a selCrush :: Crush b a -> Assoc -> a -> b -> b -- | Associativity of the binary operator used for crush data Assoc -- | Left-associative AssocLeft :: Assoc -- | Right-associative AssocRight :: Assoc -- | Apply a function (a -> b -> b) to each element -- (a) of a container (f a) and an accumulator value -- (b) to produce an accumulated result (b). -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use crushr or crushl. crush :: (FRep (Crush b) f) => Assoc -> (a -> b -> b) -> b -> f a -> b -- | A left-associative variant of crush. crushl :: (FRep (Crush b) f) => (a -> b -> b) -> b -> f a -> b -- | A right-associative variant of crush. crushr :: (FRep (Crush b) f) => (a -> b -> b) -> b -> f a -> b -- | Flatten the elements of a container into a list. -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use flattenr or -- flattenl. flatten :: (FRep (Crush [a]) f) => Assoc -> f a -> [a] -- | A left-associative variant of flatten. -- -- Note that, for a list ls :: [a], flattenl ls == reverse -- ls. flattenl :: (FRep (Crush [a]) f) => f a -> [a] -- | A right-associative variant of flatten. -- -- Note that, for a list ls :: [a], flattenr ls == ls. flattenr :: (FRep (Crush [a]) f) => f a -> [a] -- | Extract the first element of a container. If the container is empty, -- return Nothing. -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use firstr or firstl. first :: (FRep (Crush [a]) f) => Assoc -> f a -> Maybe a -- | A left-associative variant of first. -- -- Note that, for a list ls :: [a], fromJust (firstl ls) == -- last ls. firstl :: (FRep (Crush [a]) f) => f a -> Maybe a -- | A right-associative variant of first. -- -- Note that, for a list ls :: [a], fromJust (firstr ls) == -- head ls. firstr :: (FRep (Crush [a]) f) => f a -> Maybe a -- | Compute the conjunction of all elements in a container. This is a -- generalization of the Prelude function of the same name. and :: (FRep (Crush Bool) f) => f Bool -> Bool -- | Compute the disjunction of all elements in a container. This is a -- generalization of the Prelude function of the same name. or :: (FRep (Crush Bool) f) => f Bool -> Bool -- | Determine if any element in a container satisfies the predicate -- p. This is a generalization of the Prelude function of the -- same name. any :: (FRep (Crush Bool) f) => (a -> Bool) -> f a -> Bool -- | Determine if all elements in a container satisfy the predicate -- p. This is a generalization the Prelude function of the same -- name. all :: (FRep (Crush Bool) f) => (a -> Bool) -> f a -> Bool -- | Compute the sum of all elements in a container. This is a -- generalization of the Prelude function of the same name. sum :: (Num a, FRep (Crush a) f) => f a -> a -- | Compute the product of all elements in a container. This is a -- generalization of the Prelude function of the same name. product :: (Num a, FRep (Crush a) f) => f a -> a -- | Determine the minimum element of a container. If the container is -- empty, return Nothing. This is a generalization of the Prelude -- function of the same name. minimum :: (Rep Compare a, FRep (Crush (Maybe a)) f) => f a -> Maybe a -- | Determine the maximum element of a container. If the container is -- empty, return Nothing. This is a generalization of the Prelude -- function of the same name. maximum :: (Rep Compare a, FRep (Crush (Maybe a)) f) => f a -> Maybe a -- | Determine if an element is a member of a container. This is a -- generalization of the Prelude function of the same name. elem :: (Rep Compare a, FRep (Crush Bool) f) => a -> f a -> Bool -- | Determine if an element is not a member of a container. This is a -- generalization of the Prelude function of the same name. notElem :: (Rep Compare a, FRep (Crush Bool) f) => a -> f a -> Bool instance Generic (Crush b) -- | Summary: Generic function that enumerates the values of a datatype. -- -- enum generates a list of the values of a datatypes. It will -- produce all values of all supported datatypes (with only a few -- exceptions [1]). For datatypes that have an infinite enumeration (e.g. -- Integer and [a]), enum produces an infinite -- list. -- -- A number of the techniques used to write enum came from a talk -- by Mark Jones at the 2008 Advanced Functional Programming Summer -- School. The authors gratefully acknowledge his contribution. -- -- module Generics.EMGM.Functions.Enum -- | The type of a generic function that takes no arguments and returns a -- list of some type. newtype Enum a Enum :: [a] -> Enum a selEnum :: Enum a -> [a] -- | Enumerate the values of a datatype. If the number of values is -- infinite, the result will be an infinite list. The remaining functions -- are derived from enum. enum :: (Rep Enum a) => [a] -- | Enumerate the first n values of a datatype. This is a -- shortcut for genericTake n (enum). enumN :: (Integral n, Rep Enum a) => n -> [a] -- | Returns the first element of the enumeration from enum. This is -- often called the neutral or empty value. empty :: (Rep Enum a) => a instance Generic Enum -- | Summary: Generic function that applies a (non-generic) function to all -- elements contained in a polymorphic datatype. -- -- map is a generic version of the Prelude map -- function. It works on all supported container datatypes of kind * -- -> *. The map function is equivalent to fmap -- after deriving Functor if that were possible. module Generics.EMGM.Functions.Map -- | The type of a generic function that takes a value of one type and -- returns a value of a different type. newtype Map a b Map :: (a -> b) -> Map a b selMap :: Map a b -> a -> b -- | Apply a function to all elements of a container datatype (kind * -- -> *). map :: (FRep2 Map f) => (a -> b) -> f a -> f b -- | Replace all a-values in as with b. replace :: (FRep2 Map f) => f a -> b -> f b -- | Given a datatype F a b, bimap f g applies the -- function f :: a -> c to every a-element and the -- function g :: b -> d to every b-element. The -- result is a value with transformed elements: F c d. bimap :: (BiFRep2 Map f) => (a -> c) -> (b -> d) -> f a b -> f c d instance Generic2 Map -- | Summary: Generic functions that parse strings to produce values. -- -- The functions in this module involve generically parsing a string and -- producing a value. They rely on the return type to determine the -- structure for parsing. Often, this can be determined by the type -- checker, but you will occasionally need to give an explicit type -- signature. -- -- The underlying parser is designed to be as similar to deriving -- Read (as implemented by GHC) as possible. Refer to documentation -- in Text.Read for details. -- -- Since this library does not have access to the syntax of a -- data declaration, it relies on ConDescr for -- information. It is important that ConDescr accurately describe, -- for each constructor, the name, record labels (in same order as -- declared) if present, and fixity. -- -- See also Generics.EMGM.Functions.Show. module Generics.EMGM.Functions.Read -- | The type of a generic function that takes a constructor-type argument -- and returns a parser combinator for some type. newtype Read a Read :: (ConType -> ReadPrec a) -> Read a selRead :: Read a -> ConType -> ReadPrec a -- | Generate a ReadPrec parser combinator for the datatype -- a that handles operator precedence. This uses the library in -- Text.ParserCombinators.ReadPrec and should be similar to a -- derived implementation of Text.Read.readPrec. readPrec :: (Rep Read a) => ReadPrec a -- | Generate a ReadP parser combinator for the datatype a. -- This can be used with Text.ParserCombinators.ReadP. readP :: (Rep Read a) => Int -> ReadP a -- | Attempt to parse a value from the front of the string using the given -- precedence. readsPrec returns a list of (parsed value, -- remaining string) pairs. If parsing fails, readsPrec returns an -- empty list. readsPrec :: (Rep Read a) => Int -> ReadS a -- | A variant of readsPrec with the minimum precedence (0). reads :: (Rep Read a) => ReadS a -- | A variant of reads that returns Just value on a -- successful parse. Otherwise, read returns Nothing. Note -- that a successful parse requires the input to be completely consumed. read :: (Rep Read a) => String -> Maybe a instance [overlap ok] (Rep Read a, Rep Read b, Rep Read c, Rep Read d, Rep Read e, Rep Read f, Rep Read h) => Rep Read (a, b, c, d, e, f, h) instance [overlap ok] (Rep Read a, Rep Read b, Rep Read c, Rep Read d, Rep Read e, Rep Read f) => Rep Read (a, b, c, d, e, f) instance [overlap ok] (Rep Read a, Rep Read b, Rep Read c, Rep Read d, Rep Read e) => Rep Read (a, b, c, d, e) instance [overlap ok] (Rep Read a, Rep Read b, Rep Read c, Rep Read d) => Rep Read (a, b, c, d) instance [overlap ok] (Rep Read a, Rep Read b, Rep Read c) => Rep Read (a, b, c) instance [overlap ok] (Rep Read a, Rep Read b) => Rep Read (a, b) instance [overlap ok] Rep Read () instance [overlap ok] Rep Read String instance [overlap ok] (Rep Read a) => Rep Read [a] instance [overlap ok] Generic Read -- | Summary: Generic functions that convert values to readable strings. -- -- The functions in this module involve generically producing a string -- from a value of a supported datatype. The functions showsPrec -- and show are modeled after those in the class Show, -- and shows after the related function of the same name. -- -- The underlying unparser is designed to be as similar to deriving -- Show as possible. Refer to documentation in Text.Show for -- details. -- -- Since this library does not have access to the syntax of a -- data declaration, it relies on ConDescr for -- information. It is important that ConDescr accurately describe, -- for each constructor, the name, arity, record labels (in same order as -- declared) if present, and fixity. -- -- See also Generics.EMGM.Functions.Read. module Generics.EMGM.Functions.Show -- | The type of a generic function that takes a constructor-type argument, -- a number (precedence), and a value and returns a ShowS -- function. newtype Show a Show :: (ConType -> Int -> a -> ShowS) -> Show a selShow :: Show a -> ConType -> Int -> a -> ShowS -- | Convert a value to a readable string starting with the operator -- precedence of the enclosing context. showsPrec :: (Rep Show a) => Int -> a -> ShowS -- | A variant of showsPrec with the minimum precedence (0). shows :: (Rep Show a) => a -> ShowS -- | A variant of shows that returns a String instead of -- ShowS. show :: (Rep Show a) => a -> String instance [overlap ok] (Rep Show a, Rep Show b, Rep Show c, Rep Show d, Rep Show e, Rep Show f, Rep Show h) => Rep Show (a, b, c, d, e, f, h) instance [overlap ok] (Rep Show a, Rep Show b, Rep Show c, Rep Show d, Rep Show e, Rep Show f) => Rep Show (a, b, c, d, e, f) instance [overlap ok] (Rep Show a, Rep Show b, Rep Show c, Rep Show d, Rep Show e) => Rep Show (a, b, c, d, e) instance [overlap ok] (Rep Show a, Rep Show b, Rep Show c, Rep Show d) => Rep Show (a, b, c, d) instance [overlap ok] (Rep Show a, Rep Show b, Rep Show c) => Rep Show (a, b, c) instance [overlap ok] (Rep Show a, Rep Show b) => Rep Show (a, b) instance [overlap ok] Rep Show () instance [overlap ok] Rep Show String instance [overlap ok] (Rep Show a) => Rep Show [a] instance [overlap ok] Generic Show -- | Summary: Generic function that applies a (non-generic) function to -- every pair of corresponding elements in two structurally equivalent -- polymorphic values to produce a third (also structurally equivalent) -- value with the result of each application in every element location. -- -- zipWith is a generic version of the Prelude -- zipWith function. It works on all supported container -- datatypes of kind * -> *. -- -- The important concepts for zipWith are structural -- equivalence and corresponding elements. A regular, -- algebraic datatype can be visualized as some sort of tree representing -- its structure. For zipWith to be successful (and not return -- Nothing), its two container arguments must have exactly the -- same tree shape. If the shapes of the arguments differ, then it is -- unclear what the shape of the result is supposed to be. As a result, -- zipWith safely returns Nothing. -- -- Corresponding elements are those elements that are located in the same -- place in the tree of each argument. If you were to traverse the tree -- to get to element x in one tree, then its corresponding element y in -- the other tree should require the exact same path to reach it. -- -- See also Generics.EMGM.Functions.UnzipWith. module Generics.EMGM.Functions.ZipWith -- | The type of a generic function that takes two arguments of two -- different types and optionally returns a value of a third type. newtype ZipWith a b c ZipWith :: (a -> b -> Maybe c) -> ZipWith a b c selZipWith :: ZipWith a b c -> a -> b -> Maybe c -- | Combine two structurally equivalent containers into one by applying a -- function to every corresponding pair of elements. Returns -- Nothing if f a and f b have different shapes. zipWith :: (FRep3 ZipWith f) => (a -> b -> c) -> f a -> f b -> Maybe (f c) -- | Combine two containers into a single container with pairs of the -- original elements. See zipWith for restrictions. This is a -- generic version of the Prelude function of the same name. zip :: (FRep3 ZipWith f) => f a -> f b -> Maybe (f (a, b)) instance Generic3 ZipWith -- | Summary: Generic function that applies a (non-generic) function to -- every element in a value, splitting the element into two. The result -- are two structurally equivalent values, one with the elements from the -- first component of the splitting function and the other with the -- elements from the second component. -- -- unzipWith can be seen as the dual of the zipWith -- function. It has no Prelude counterpart. -- -- See also Generics.EMGM.Functions.ZipWith. module Generics.EMGM.Functions.UnzipWith -- | The type of a generic function that takes an argument of one type and -- returns a pair of values with two different types. newtype UnzipWith a b c UnzipWith :: (a -> (b, c)) -> UnzipWith a b c selUnzipWith :: UnzipWith a b c -> a -> (b, c) -- | Splits a container into two structurally equivalent containers by -- applying a function to every element, which splits it into two -- corresponding elements. unzipWith :: (FRep3 UnzipWith f) => (a -> (b, c)) -> f a -> (f b, f c) -- | Transforms a container of pairs into a container of first components -- and a container of second components. This is a generic version of the -- Prelude function of the same name. unzip :: (FRep3 UnzipWith f) => f (a, b) -> (f a, f b) instance Generic3 UnzipWith -- | Exports all modules in the Generics.EMGM.Functions.* hierarchy. module Generics.EMGM.Functions -- | Summary: Generic representation and instances for Bool. -- -- The main purpose of this module is to export the instances for the -- representation dispatcher Rep. For the rare cases in which it -- is needed, this module also exports the embedding-projection pair and -- constructor description. module Generics.EMGM.Data.Bool -- | Embedding-projection pair for Bool epBool :: EP Bool (Unit :+: Unit) -- | Constructor description for False conFalse :: ConDescr -- | Constructor description for True conTrue :: ConDescr instance [overlap ok] Rep (Collect Bool) Bool instance [overlap ok] (Generic g) => Rep g Bool -- | Summary: Generic representation and instances for Either. -- -- The main purpose of this module is to export the instances for the -- representation dispatchers Rep and BiFRep2. For the rare -- cases in which it is needed, this module also exports the -- embedding-projection pair and constructor description. module Generics.EMGM.Data.Either -- | Embedding-projection pair for Either epEither :: EP (Either a b) (a :+: b) -- | Constructor description for Left conLeft :: ConDescr -- | Constructor description for Right conRight :: ConDescr instance [overlap ok] Rep (Collect (Either a b)) (Either a b) instance [overlap ok] (Generic2 g) => BiFRep2 g Either instance [overlap ok] (Generic g, Rep g a, Rep g b) => Rep g (Either a b) -- | Summary: Generic representation and instances for lists. -- -- The main purpose of this module is to export the instances for the -- representation dispatchers Rep, FRep, FRep2, and -- FRep3. For the rare cases in which it is needed, this module -- also exports the embedding-projection pair and constructor -- description. module Generics.EMGM.Data.List -- | Embedding-projection pair for lists epList :: EP [a] (Unit :+: (a :*: [a])) -- | Constructor description for ''nil'': [] conNil :: ConDescr -- | Constructor description for ''cons'': (:) conCons :: ConDescr instance [overlap ok] Rep (Collect [a]) [a] instance [overlap ok] (Generic3 g) => FRep3 g [] instance [overlap ok] (Generic2 g) => FRep2 g [] instance [overlap ok] (Generic g) => FRep g [] instance [overlap ok] (Generic g, Rep g a) => Rep g [a] -- | Summary: Generic representation and instances for Maybe. -- -- The main purpose of this module is to export the instances for the -- representation dispatchers Rep, FRep, FRep2, and -- FRep3. For the rare cases in which it is needed, this module -- also exports the embedding-projection pair and constructor -- description. module Generics.EMGM.Data.Maybe -- | Embedding-projection pair for Maybe epMaybe :: EP (Maybe a) (Unit :+: a) -- | Constructor description for Nothing conNothing :: ConDescr -- | Constructor description for Just conJust :: ConDescr instance [overlap ok] Rep (Collect (Maybe a)) (Maybe a) instance [overlap ok] (Generic3 g) => FRep3 g Maybe instance [overlap ok] (Generic2 g) => FRep2 g Maybe instance [overlap ok] (Generic g) => FRep g Maybe instance [overlap ok] (Generic g, Rep g a) => Rep g (Maybe a) -- | Summary: Generic representation and instances for tuples of arity 0 -- (''unit'') and 2 to 7. -- -- The main purpose of this module is to export the instances for the -- representation dispatchers, Rep and (where appropriate) -- BiFRep2. For the rare cases in which it is needed, this module -- also exports the embedding-projection pair and constructor -- description. module Generics.EMGM.Data.Tuple -- | Embedding-projection pair for () epTuple0 :: EP () Unit -- | Constructor description for () conTuple0 :: ConDescr -- | Embedding-projection pair for (a,b) epTuple2 :: EP (a, b) (a :*: b) -- | Constructor description for (a,b) conTuple2 :: ConDescr -- | Embedding-projection pair for (a,b,c) epTuple3 :: EP (a, b, c) (a :*: (b :*: c)) -- | Constructor description for (a,b,c) conTuple3 :: ConDescr -- | Embedding-projection pair for (a,b,c,d) epTuple4 :: EP (a, b, c, d) (a :*: (b :*: (c :*: d))) -- | Constructor description for (a,b,c,d) conTuple4 :: ConDescr -- | Embedding-projection pair for (a,b,c,d,e) epTuple5 :: EP (a, b, c, d, e) (a :*: (b :*: (c :*: (d :*: e)))) -- | Constructor description for (a,b,c,d,e) conTuple5 :: ConDescr -- | Embedding-projection pair for (a,b,c,d,e,f) epTuple6 :: EP (a, b, c, d, e, f) (a :*: (b :*: (c :*: (d :*: (e :*: f))))) -- | Constructor description for (a,b,c,d,e,f) conTuple6 :: ConDescr -- | Embedding-projection pair for (a,b,c,d,e,f,h) epTuple7 :: EP (a, b, c, d, e, f, h) (a :*: (b :*: (c :*: (d :*: (e :*: (f :*: h)))))) -- | Constructor description for (a,b,c,d,e,f,h) conTuple7 :: ConDescr instance [overlap ok] Rep (Collect (a, b, c, d, e, f, h)) (a, b, c, d, e, f, h) instance [overlap ok] Rep (Collect (a, b, c, d, e, f)) (a, b, c, d, e, f) instance [overlap ok] Rep (Collect (a, b, c, d, e)) (a, b, c, d, e) instance [overlap ok] Rep (Collect (a, b, c, d)) (a, b, c, d) instance [overlap ok] Rep (Collect (a, b, c)) (a, b, c) instance [overlap ok] Rep (Collect (a, b)) (a, b) instance [overlap ok] Rep (Collect ()) () instance [overlap ok] (Generic2 g) => BiFRep2 g (,) instance [overlap ok] (Generic g, Rep g a, Rep g b, Rep g c, Rep g d, Rep g e, Rep g f, Rep g h) => Rep g (a, b, c, d, e, f, h) instance [overlap ok] (Generic g, Rep g a, Rep g b, Rep g c, Rep g d, Rep g e, Rep g f) => Rep g (a, b, c, d, e, f) instance [overlap ok] (Generic g, Rep g a, Rep g b, Rep g c, Rep g d, Rep g e) => Rep g (a, b, c, d, e) instance [overlap ok] (Generic g, Rep g a, Rep g b, Rep g c, Rep g d) => Rep g (a, b, c, d) instance [overlap ok] (Generic g, Rep g a, Rep g b, Rep g c) => Rep g (a, b, c) instance [overlap ok] (Generic g, Rep g a, Rep g b) => Rep g (a, b) instance [overlap ok] (Generic g) => Rep g () -- | Summary: Generic representation and instances for Template Haskell -- types. -- -- The main purpose of this module is to export the instances for the -- representation dispatcher Rep. For the rare cases in which it -- is needed, this module also exports the embedding-projection pair and -- constructor description. -- -- NOTE: The exported values are not explicitly documented, -- because there is a large number and they are all generated with -- Template Haskell expressions. For a detailed look, use the -- :browse command in GHCi. module Generics.EMGM.Data.TH -- | Exports all modules in Generics.EMGM.Data.* for convenience. module Generics.EMGM.Data -- | EMGM is "Extensible and Modular Generics for the Masses," a library -- for datatype-generic programming in Haskell. -- -- This module exports the most commonly used types, classes, and -- functions. The documentation is organized by topic for convenient -- access. -- -- For more in-depth documentation, refer to one of the modules in these -- hierarchies: -- -- module Generics.EMGM -- | The "unit" encodes a constructor with no arguments. An analogous -- standard Haskell type is (). data Unit -- | The only value of type Unit (ignoring _|_). Unit :: Unit -- | The "sum" encodes 2 constructor alternatives. An analogous standard -- Haskell type is Either a b. data (:+:) a b -- | Left alternative L :: a -> :+: a b -- | Right alternative R :: b -> :+: a b -- | The "product" encodes 2 constructor arguments. An analogous standard -- Haskell type is (a, b). data (:*:) a b -- | A pair of arguments (:*:) :: a -> b -> :*: a b -- | The embedding-projection pair contains two functions for converting -- between the datatype and its representation. An EP value -- preserves an isomorphism (ignoring _|_s) between a datatype -- and its structure representation. data EP d r EP :: (d -> r) -> (r -> d) -> EP d r -- | Embed a datatype into its representation. from :: EP d r -> (d -> r) -- | Project datatype from its representation. to :: EP d r -> (r -> d) -- | A constructor description containing useful meta-information about the -- syntax used in the data declaration. This is particularly useful in -- Read and Show but may also be helpful in other generic -- functions. -- -- NOTE: It is important that the ConDescr value accurately -- describe the syntax in a constructor declaration. An incorrect -- description may lead to faulty Read or Show operation. data ConDescr ConDescr :: String -> Int -> [String] -> Fixity -> ConDescr -- | Name of the constructor. If it is infix, don't provide parentheses. conName :: ConDescr -> String -- | Arity or number of arguments. conArity :: ConDescr -> Int -- | A list of labels used in record syntax. They must be declared in the -- same order as the data declaration. The list should be empty -- if the constructor is not a record. conLabels :: ConDescr -> [String] -- | Infix or not, associativity, precedence. conFixity :: ConDescr -> Fixity -- | The constructor type used in Read and Show to determine -- how to parse or print the constructor. data ConType -- | Standard (function-type, nonfix) ConStd :: ConType -- | Record-style (nonfix or infix) ConRec :: [String] -> ConType -- | Infix (no record syntax) ConIfx :: String -> ConType -- | An identifier's fixity, associativity, and precedence. If not infix -- (Nonfix), the associativity and precedence of the identifier is -- the same as function application. If infix, the associativity is -- indicated by the constructor and the precedence is an argument to it. data Fixity -- | Not infix. Associativity and precedence are the same as function -- application. Nonfix :: Fixity -- | Non-associative infix with precedence. Infix :: Prec -> Fixity -- | Left-associative infix with precedence. Infixl :: Prec -> Fixity -- | Right-associative Infix with precedence. Infixr :: Prec -> Fixity -- | Get the precedence of a fixity value. prec :: Fixity -> Prec -- | Maximum precedence: 11 maxPrec :: Prec -- | Precedence for function application: 10 appPrec :: Prec -- | Precedence for record construction: 11 recPrec :: Prec -- | The Generic representation dispatcher for monomorphic types -- (kind *). Every structure type and supported datatype should -- have an instance of Rep. (No default implementation.) class Rep g a rep :: (Rep g a) => g a -- | The Generic representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep g f frep :: (FRep g f) => g a -> g (f a) -- | The Generic2 representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep2 g f frep2 :: (FRep2 g f) => g a b -> g (f a) (f b) -- | The Generic3 representation dispatcher for functor types (kind -- * -> *), sometimes called container types. (No default -- implementation.) class FRep3 g f frep3 :: (FRep3 g f) => g a b c -> g (f a) (f b) (f c) -- | The Generic2 representation dispatcher for bifunctor types -- (kind * -> * -> *). (No default implementation.) class BiFRep2 g f bifrep2 :: (BiFRep2 g f) => g a1 b1 -> g a2 b2 -> g (f a1 a2) (f b1 b2) -- | This class forms the foundation for defining generic functions with a -- single generic argument. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic g rconstant :: (Generic g, Enum a, Eq a, Ord a, Read a, Show a) => g a rint :: (Generic g) => g Int rinteger :: (Generic g) => g Integer rfloat :: (Generic g) => g Float rdouble :: (Generic g) => g Double rchar :: (Generic g) => g Char runit :: (Generic g) => g Unit rsum :: (Generic g) => g a -> g b -> g (a :+: b) rprod :: (Generic g) => g a -> g b -> g (a :*: b) rcon :: (Generic g) => ConDescr -> g a -> g a rtype :: (Generic g) => EP b a -> g a -> g b -- | This class forms the foundation for defining generic functions with -- two generic arguments. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic2 g rconstant2 :: (Generic2 g, Enum a, Eq a, Ord a, Read a, Show a) => g a a rint2 :: (Generic2 g) => g Int Int rinteger2 :: (Generic2 g) => g Integer Integer rfloat2 :: (Generic2 g) => g Float Float rdouble2 :: (Generic2 g) => g Double Double rchar2 :: (Generic2 g) => g Char Char runit2 :: (Generic2 g) => g Unit Unit rsum2 :: (Generic2 g) => g a1 a2 -> g b1 b2 -> g (a1 :+: b1) (a2 :+: b2) rprod2 :: (Generic2 g) => g a1 a2 -> g b1 b2 -> g (a1 :*: b1) (a2 :*: b2) rcon2 :: (Generic2 g) => ConDescr -> g a1 a2 -> g a1 a2 rtype2 :: (Generic2 g) => EP a2 a1 -> EP b2 b1 -> g a1 b1 -> g a2 b2 -- | This class forms the foundation for defining generic functions with -- three generic arguments. Each method represents a type case. The class -- includes cases for primitive types, cases for the structural -- representation, and the rtype case for adding support for new -- datatypes. class Generic3 g rconstant3 :: (Generic3 g, Enum a, Eq a, Ord a, Read a, Show a) => g a a a rint3 :: (Generic3 g) => g Int Int Int rinteger3 :: (Generic3 g) => g Integer Integer Integer rfloat3 :: (Generic3 g) => g Float Float Float rdouble3 :: (Generic3 g) => g Double Double Double rchar3 :: (Generic3 g) => g Char Char Char runit3 :: (Generic3 g) => g Unit Unit Unit rsum3 :: (Generic3 g) => g a1 a2 a3 -> g b1 b2 b3 -> g (a1 :+: b1) (a2 :+: b2) (a3 :+: b3) rprod3 :: (Generic3 g) => g a1 a2 a3 -> g b1 b2 b3 -> g (a1 :*: b1) (a2 :*: b2) (a3 :*: b3) rcon3 :: (Generic3 g) => ConDescr -> g a1 a2 a3 -> g a1 a2 a3 rtype3 :: (Generic3 g) => EP a2 a1 -> EP b2 b1 -> EP c2 c1 -> g a1 b1 c1 -> g a2 b2 c2 -- | Derive all appropriate instances for using EMGM with a datatype. -- -- Here is an example module that shows how to use derive: -- --
--   {-# LANGUAGE TemplateHaskell       #-}
--   {-# LANGUAGE MultiParamTypeClasses #-}
--   {-# LANGUAGE FlexibleContexts      #-}
--   {-# LANGUAGE FlexibleInstances     #-}
--   {-# LANGUAGE OverlappingInstances  #-}
--   {-# LANGUAGE UndecidableInstances  #-}
--   
-- --
--   module Example where
--   import Generics.EMGM
--   data T a = C a Int
--   
-- --
--   $(derive ''T)
--   
-- -- The Template Haskell derive declaration in the above example -- generates the following (annotated) code: -- --
--   -- (1) Constructor description declarations (1 per constructor)
--   
-- --
--   conC :: ConDescr
--   conC = ConDescr "C" 2 [] Nonfix
--   
-- --
--   -- (2) Embedding-projection pair declarations (1 per type)
--   
-- --
--   epT :: EP (T a) (a :*: Int)
--   epT = EP fromT toT
--     where fromT (C v1 v2) = v1 :*: v2
--           toT (v1 :*: v2) = C v1 v2
--   
-- --
--   -- (3) Rep instance (1 per type)
--   
-- --
--   instance (Generic g, Rep g a, Rep g Int) => Rep g (T a) where
--     rep = rtype epT (rcon conC (rprod rep rep))
--   
-- --
--   -- (4) Higher arity instances if applicable (either FRep, FRep2, and
--   -- FRep3 together, or BiFRep2)
--   
-- --
--   instance (Generic g) => FRep g T where
--     frep ra = rtype epT (rcon conC (rprod ra rint))
--   
-- --
--   -- In this case, similar instances would be generated for FRep2 and FRep3.
--   
-- --
--   -- (5) Function-specific instances (1 per type)
--   
-- --
--   instance Rep (Collect Char) Char where
--     rep = Collect (:[])
--   
-- -- Note that the constructor description conC and -- embedding-project pair epT are top-level values. This allows -- them to be shared between multiple instances. If these names conflict -- with your own, you may want to put the $(derive ...) -- declaration in its own module and restrict the export list. derive :: Name -> Q [Dec] -- | Same as derive except that you can pass a list of name -- modifications to the deriving mechanism. -- -- Use deriveWith if: -- --
    --
  1. You want to use the generated constructor descriptions or -- embedding-projection pairs and one of your constructors or -- types is an infix symbol. In other words, if you have a constructor -- :*, you cannot refer to the (invalid) generated name for its -- description, con:*. It appears that GHC has no problem with -- that name internally, so this is only if you want access to it.
  2. --
  3. You want to define your own constructor description. This allows -- you to give a precise implementation different from the one generated -- for you.
  4. --
-- -- For option 1, use ChangeTo as in this example: -- --
--   data U = Int :* Char
--   $(deriveWith [(":*", ChangeTo "Star")] ''U)
--   x = ... conStar ...
--   
-- -- For option 2, use DefinedAs as in this example: -- --
--   data V = (:=) { i :: Int, j :: Char }
--   $(deriveWith [(":=", DefinedAs "Equals")] ''V)
--   conEquals = ConDescr ":=" 2 [] (Infix 4)
--   
-- -- Using the example for option 2 with -- Generics.EMGM.Functions.Show will print values of V as -- infix instead of the default record syntax. -- -- Note that only the first pair with its first field matching the type -- or constructor name in the Modifiers list will be used. Any -- other matches will be ignored. deriveWith :: Modifiers -> Name -> Q [Dec] -- | Modify the action taken for a given name. data Modifier -- | Change the syntactic name (of a type or constructor) to the argument -- in the generated EP or ConDescr value. This results in a value named -- epX or conX if the argument is "X". ChangeTo :: String -> Modifier -- | Use this for the name of a user-defined constructor description -- instead of a generated one. The generated code assumes the existance -- of conX :: ConDescr (in scope) if the argument is -- "X". DefinedAs :: String -> Modifier -- | List of pairs mapping a (type or constructor) name to a modifier -- action. type Modifiers = [(String, Modifier)] -- | The type of a generic function that takes a value of one type and -- returns a list of values of another type. -- -- For datatypes to work with Collect, a special instance must be given. -- This instance is trivial to write. Given a type D, the -- Rep instance looks like this: -- --
--   {-# LANGUAGE OverlappingInstances #-}
--   
--   data D = ...
--   
--   instance Rep (Collect D) D where
--     rep = Collect (:[])
--   
-- -- (Note the requirement of overlapping instances.) This instance -- triggers when the result type (the first D) matches some -- value type (the second D) contained within the argument to -- collect. See the source of this module for more examples. newtype Collect b a Collect :: (a -> [b]) -> Collect b a selCollect :: Collect b a -> a -> [b] -- | Collect values of type b from some value of type a. -- An empty list means no values were collected. If you expected -- otherwise, be sure that you have an instance such as Rep -- (Collect B) B for the type B that you are -- collecting. -- -- collect works by searching a datatype for values that are the -- same type as the return type specified. Here are some examples using -- the same value but different return types: -- --
--   ghci> let x = [Left 1, Right a, Left 2] :: [Either Int Char]
--   ghci> collect x :: [Int]
--   [1,2]
--   ghci> collect x :: [Char]
--   "a"
--   ghci> collect x == x
--   True
--   
-- -- Note that the numerical constants have been declared Int -- using the type annotation. Since these natively have the type Num -- a => a, you may need to give explicit types. By design, there -- is no connection that can be inferred between the return type and the -- argument type. -- -- collect only works if there is an instance for the return -- type as described in the newtype Collect. collect :: (Rep (Collect b) a) => a -> [b] -- | The type of a generic function that takes two values of the same type -- and returns an Ordering. newtype Compare a Compare :: (a -> a -> Ordering) -> Compare a selCompare :: Compare a -> a -> a -> Ordering -- | Compare two values and return an Ordering (i.e. LT, -- GT, or EQ). This is implemented exactly as if the -- datatype was deriving Ord. compare :: (Rep Compare a) => a -> a -> Ordering -- | Equal to. Returns x == y. eq :: (Rep Compare a) => a -> a -> Bool -- | Not equal to. Returns x /= y. neq :: (Rep Compare a) => a -> a -> Bool -- | Less than. Returns x < y. lt :: (Rep Compare a) => a -> a -> Bool -- | Less than or equal to. Returns x <= y. lteq :: (Rep Compare a) => a -> a -> Bool -- | Greater than. Returns x > y. gt :: (Rep Compare a) => a -> a -> Bool -- | Greater than or equal to. Returns x >= y. gteq :: (Rep Compare a) => a -> a -> Bool -- | The minimum of two values. min :: (Rep Compare a) => a -> a -> a -- | The maximum of two values. max :: (Rep Compare a) => a -> a -> a -- | The type of a generic function that takes an associativity and two -- arguments of different types and returns a value of the type of the -- second. newtype Crush b a Crush :: (Assoc -> a -> b -> b) -> Crush b a selCrush :: Crush b a -> Assoc -> a -> b -> b -- | Associativity of the binary operator used for crush data Assoc -- | Left-associative AssocLeft :: Assoc -- | Right-associative AssocRight :: Assoc -- | Apply a function (a -> b -> b) to each element -- (a) of a container (f a) and an accumulator value -- (b) to produce an accumulated result (b). -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use crushr or crushl. crush :: (FRep (Crush b) f) => Assoc -> (a -> b -> b) -> b -> f a -> b -- | A left-associative variant of crush. crushl :: (FRep (Crush b) f) => (a -> b -> b) -> b -> f a -> b -- | A right-associative variant of crush. crushr :: (FRep (Crush b) f) => (a -> b -> b) -> b -> f a -> b -- | Flatten the elements of a container into a list. -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use flattenr or -- flattenl. flatten :: (FRep (Crush [a]) f) => Assoc -> f a -> [a] -- | A left-associative variant of flatten. -- -- Note that, for a list ls :: [a], flattenl ls == reverse -- ls. flattenl :: (FRep (Crush [a]) f) => f a -> [a] -- | A right-associative variant of flatten. -- -- Note that, for a list ls :: [a], flattenr ls == ls. flattenr :: (FRep (Crush [a]) f) => f a -> [a] -- | Extract the first element of a container. If the container is empty, -- return Nothing. -- -- This is the most general form in which you must specify the -- associativity. You may prefer to use firstr or firstl. first :: (FRep (Crush [a]) f) => Assoc -> f a -> Maybe a -- | A left-associative variant of first. -- -- Note that, for a list ls :: [a], fromJust (firstl ls) == -- last ls. firstl :: (FRep (Crush [a]) f) => f a -> Maybe a -- | A right-associative variant of first. -- -- Note that, for a list ls :: [a], fromJust (firstr ls) == -- head ls. firstr :: (FRep (Crush [a]) f) => f a -> Maybe a -- | Compute the conjunction of all elements in a container. This is a -- generalization of the Prelude function of the same name. and :: (FRep (Crush Bool) f) => f Bool -> Bool -- | Compute the disjunction of all elements in a container. This is a -- generalization of the Prelude function of the same name. or :: (FRep (Crush Bool) f) => f Bool -> Bool -- | Determine if any element in a container satisfies the predicate -- p. This is a generalization of the Prelude function of the -- same name. any :: (FRep (Crush Bool) f) => (a -> Bool) -> f a -> Bool -- | Determine if all elements in a container satisfy the predicate -- p. This is a generalization the Prelude function of the same -- name. all :: (FRep (Crush Bool) f) => (a -> Bool) -> f a -> Bool -- | Compute the sum of all elements in a container. This is a -- generalization of the Prelude function of the same name. sum :: (Num a, FRep (Crush a) f) => f a -> a -- | Compute the product of all elements in a container. This is a -- generalization of the Prelude function of the same name. product :: (Num a, FRep (Crush a) f) => f a -> a -- | Determine the minimum element of a container. If the container is -- empty, return Nothing. This is a generalization of the Prelude -- function of the same name. minimum :: (Rep Compare a, FRep (Crush (Maybe a)) f) => f a -> Maybe a -- | Determine the maximum element of a container. If the container is -- empty, return Nothing. This is a generalization of the Prelude -- function of the same name. maximum :: (Rep Compare a, FRep (Crush (Maybe a)) f) => f a -> Maybe a -- | Determine if an element is a member of a container. This is a -- generalization of the Prelude function of the same name. elem :: (Rep Compare a, FRep (Crush Bool) f) => a -> f a -> Bool -- | Determine if an element is not a member of a container. This is a -- generalization of the Prelude function of the same name. notElem :: (Rep Compare a, FRep (Crush Bool) f) => a -> f a -> Bool -- | The type of a generic function that takes no arguments and returns a -- list of some type. newtype Enum a Enum :: [a] -> Enum a selEnum :: Enum a -> [a] -- | Enumerate the values of a datatype. If the number of values is -- infinite, the result will be an infinite list. The remaining functions -- are derived from enum. enum :: (Rep Enum a) => [a] -- | Enumerate the first n values of a datatype. This is a -- shortcut for genericTake n (enum). enumN :: (Integral n, Rep Enum a) => n -> [a] -- | Returns the first element of the enumeration from enum. This is -- often called the neutral or empty value. empty :: (Rep Enum a) => a -- | The type of a generic function that takes a value of one type and -- returns a value of a different type. newtype Map a b Map :: (a -> b) -> Map a b selMap :: Map a b -> a -> b -- | Apply a function to all elements of a container datatype (kind * -- -> *). map :: (FRep2 Map f) => (a -> b) -> f a -> f b -- | Replace all a-values in as with b. replace :: (FRep2 Map f) => f a -> b -> f b -- | Given a datatype F a b, bimap f g applies the -- function f :: a -> c to every a-element and the -- function g :: b -> d to every b-element. The -- result is a value with transformed elements: F c d. bimap :: (BiFRep2 Map f) => (a -> c) -> (b -> d) -> f a b -> f c d -- | The type of a generic function that takes a constructor-type argument -- and returns a parser combinator for some type. newtype Read a Read :: (ConType -> ReadPrec a) -> Read a selRead :: Read a -> ConType -> ReadPrec a -- | Generate a ReadPrec parser combinator for the datatype -- a that handles operator precedence. This uses the library in -- Text.ParserCombinators.ReadPrec and should be similar to a -- derived implementation of Text.Read.readPrec. readPrec :: (Rep Read a) => ReadPrec a -- | Generate a ReadP parser combinator for the datatype a. -- This can be used with Text.ParserCombinators.ReadP. readP :: (Rep Read a) => Int -> ReadP a -- | Attempt to parse a value from the front of the string using the given -- precedence. readsPrec returns a list of (parsed value, -- remaining string) pairs. If parsing fails, readsPrec returns an -- empty list. readsPrec :: (Rep Read a) => Int -> ReadS a -- | A variant of readsPrec with the minimum precedence (0). reads :: (Rep Read a) => ReadS a -- | A variant of reads that returns Just value on a -- successful parse. Otherwise, read returns Nothing. Note -- that a successful parse requires the input to be completely consumed. read :: (Rep Read a) => String -> Maybe a -- | The type of a generic function that takes a constructor-type argument, -- a number (precedence), and a value and returns a ShowS -- function. newtype Show a Show :: (ConType -> Int -> a -> ShowS) -> Show a selShow :: Show a -> ConType -> Int -> a -> ShowS -- | Convert a value to a readable string starting with the operator -- precedence of the enclosing context. showsPrec :: (Rep Show a) => Int -> a -> ShowS -- | A variant of showsPrec with the minimum precedence (0). shows :: (Rep Show a) => a -> ShowS -- | A variant of shows that returns a String instead of -- ShowS. show :: (Rep Show a) => a -> String -- | The type of a generic function that takes an argument of one type and -- returns a pair of values with two different types. newtype UnzipWith a b c UnzipWith :: (a -> (b, c)) -> UnzipWith a b c selUnzipWith :: UnzipWith a b c -> a -> (b, c) -- | Transforms a container of pairs into a container of first components -- and a container of second components. This is a generic version of the -- Prelude function of the same name. unzip :: (FRep3 UnzipWith f) => f (a, b) -> (f a, f b) -- | Splits a container into two structurally equivalent containers by -- applying a function to every element, which splits it into two -- corresponding elements. unzipWith :: (FRep3 UnzipWith f) => (a -> (b, c)) -> f a -> (f b, f c) -- | The type of a generic function that takes two arguments of two -- different types and optionally returns a value of a third type. newtype ZipWith a b c ZipWith :: (a -> b -> Maybe c) -> ZipWith a b c selZipWith :: ZipWith a b c -> a -> b -> Maybe c -- | Combine two containers into a single container with pairs of the -- original elements. See zipWith for restrictions. This is a -- generic version of the Prelude function of the same name. zip :: (FRep3 ZipWith f) => f a -> f b -> Maybe (f (a, b)) -- | Combine two structurally equivalent containers into one by applying a -- function to every corresponding pair of elements. Returns -- Nothing if f a and f b have different shapes. zipWith :: (FRep3 ZipWith f) => (a -> b -> c) -> f a -> f b -> Maybe (f c)