-- 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:
--
--
-- - 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.
-- - 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.
-- - 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.
--
--
-- 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:
--
--
-- - 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.
-- - You want to define your own constructor description. This allows
-- you to give a precise implementation different from the one generated
-- for you.
--
--
-- 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.
--
--
-- - 1 The exceptions are Float and Double. These
-- are treated in the same way as their Enum instances are
-- treated. The result looks like this: [0.0,-1.0,1.0,-2.0,..],
-- thus skipping all non-integral values. Note that these may overflow,
-- because they are unbounded.
--
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:
--
--
-- - 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.
-- - You want to define your own constructor description. This allows
-- you to give a precise implementation different from the one generated
-- for you.
--
--
-- 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)