compdata-0.3: Compositional Data Types

Portabilitynon-portable (GHC Extensions)
Stabilityexperimental
MaintainerPatrick Bahr <paba@diku.dk>

Data.Comp.Derive

Contents

Description

This module contains functionality for automatically deriving boilerplate code using Template Haskell. Examples include instances of Functor, Foldable, and Traversable.

Synopsis

Documentation

derive :: [Name -> Q [Dec]] -> [Name] -> Q [Dec]Source

Helper function for generating a list of instances for a list of named signatures. For example, in order to derive instances Functor and ShowF for a signature Exp, use derive as follows (requires Template Haskell):

 $(derive [makeFunctor, makeShowF] [''Exp])

Derive boilerplate instances for compositional data type signatures.

ShowF

class ShowF f whereSource

Signature printing. An instance ShowF f gives rise to an instance Show (Term f).

Methods

showF :: f String -> StringSource

Instances

ShowF [] 
ShowF Maybe 
Show a[12] => ShowF ((,) a[12]) 
(ShowF f, Show p) => ShowF (:&: f p) 
(ShowF f, ShowF g) => ShowF (:+: f g) 
(Functor f, ShowF f) => ShowF (Cxt h f) 

makeShowF :: Name -> Q [Dec]Source

Derive an instance of ShowF for a type constructor of any first-order kind taking at least one argument.

EqF

class EqF f whereSource

Signature equality. An instance EqF f gives rise to an instance Eq (Term f).

Methods

eqF :: Eq a => f a -> f a -> BoolSource

Instances

EqF [] 
EqF Maybe 
Eq a[12] => EqF ((,) a[12]) 
(Eq a[12], Eq b[13]) => EqF ((,,) a[12] b[13]) 
(EqF f, EqF g) => EqF (:+: f g)

EqF is propagated through sums.

EqF f => EqF (Cxt h f)

From an EqF functor an Eq instance of the corresponding term type can be derived.

(Eq a[12], Eq b[13], Eq c[14]) => EqF ((,,,) a[12] b[13] c[14]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15]) => EqF ((,,,,) a[12] b[13] c[14] d[15]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15], Eq e[16]) => EqF ((,,,,,) a[12] b[13] c[14] d[15] e[16]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15], Eq e[16], Eq f[17]) => EqF ((,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15], Eq e[16], Eq f[17], Eq g[18]) => EqF ((,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15], Eq e[16], Eq f[17], Eq g[18], Eq h[19]) => EqF ((,,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18] h[19]) 
(Eq a[12], Eq b[13], Eq c[14], Eq d[15], Eq e[16], Eq f[17], Eq g[18], Eq h[19], Eq i[1a]) => EqF ((,,,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18] h[19] i[1a]) 

makeEqF :: Name -> Q [Dec]Source

Derive an instance of EqF for a type constructor of any first-order kind taking at least one argument.

OrdF

class EqF f => OrdF f whereSource

Signature ordering. An instance OrdF f gives rise to an instance Ord (Term f).

Methods

compareF :: Ord a => f a -> f a -> OrderingSource

Instances

OrdF [] 
OrdF Maybe 
Ord a[12] => OrdF ((,) a[12]) 
(Ord a[12], Ord b[13]) => OrdF ((,,) a[12] b[13]) 
(OrdF f, OrdF g) => OrdF (:+: f g)

OrdF is propagated through sums.

OrdF f => OrdF (Cxt h f)

From an OrdF functor an Ord instance of the corresponding term type can be derived.

(Ord a[12], Ord b[13], Ord c[14]) => OrdF ((,,,) a[12] b[13] c[14]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15]) => OrdF ((,,,,) a[12] b[13] c[14] d[15]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15], Ord e[16]) => OrdF ((,,,,,) a[12] b[13] c[14] d[15] e[16]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15], Ord e[16], Ord f[17]) => OrdF ((,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15], Ord e[16], Ord f[17], Ord g[18]) => OrdF ((,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15], Ord e[16], Ord f[17], Ord g[18], Ord h[19]) => OrdF ((,,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18] h[19]) 
(Ord a[12], Ord b[13], Ord c[14], Ord d[15], Ord e[16], Ord f[17], Ord g[18], Ord h[19], Ord i[1a]) => OrdF ((,,,,,,,,,) a[12] b[13] c[14] d[15] e[16] f[17] g[18] h[19] i[1a]) 

makeOrdF :: Name -> Q [Dec]Source

Derive an instance of OrdF for a type constructor of any first-order kind taking at least one argument.

Functor

class Functor f

The Functor class is used for types that can be mapped over. Instances of Functor should satisfy the following laws:

 fmap id  ==  id
 fmap (f . g)  ==  fmap f . fmap g

The instances of Functor for lists, Data.Maybe.Maybe and System.IO.IO satisfy these laws.

Instances

Functor [] 
Functor IO 
Functor Q 
Functor Gen 
Functor Id 
Functor ZipList 
Functor Maybe 
Functor Identity 
Functor I 
Functor ((->) r) 
Functor (Either a) 
Functor ((,) a) 
Difunctor f => Functor (f a) 
Functor (StateL s) 
Functor (StateR s) 
Functor (Const m) 
Monad m => Functor (WrappedMonad m) 
Functor (Map k) 
Functor m => Functor (ListT m) 
Functor m => Functor (MaybeT m) 
Functor m => Functor (IdentityT m) 
Functor (K a) 
Functor (K a) 
Arrow a => Functor (WrappedArrow a b) 
Functor (ContT r m) 
Functor m => Functor (ErrorT e m) 
Functor m => Functor (ReaderT r m) 
Functor m => Functor (StateT s m) 
Functor m => Functor (StateT s m) 
Functor m => Functor (WriterT w m) 
Functor m => Functor (WriterT w m) 
(Functor f, Functor g) => Functor (Compose f g) 
Functor f => Functor (:&: f a) 
(Functor f, Functor g) => Functor (:+: f g) 
Functor f => Functor (Cxt h f) 
Functor m => Functor (RWST r w s m) 
Functor m => Functor (RWST r w s m) 

makeFunctor :: Name -> Q [Dec]Source

Derive an instance of Functor for a type constructor of any first-order kind taking at least one argument.

Foldable

class Foldable t

Data structures that can be folded.

Minimal complete definition: foldMap or foldr.

For example, given a data type

 data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)

a suitable instance would be

 instance Foldable Tree where
    foldMap f Empty = mempty
    foldMap f (Leaf x) = f x
    foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r

This is suitable even for abstract types, as the monoid is assumed to satisfy the monoid laws. Alternatively, one could define foldr:

 instance Foldable Tree where
    foldr f z Empty = z
    foldr f z (Leaf x) = f x z
    foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l

Instances

makeFoldable :: Name -> Q [Dec]Source

Derive an instance of Foldable for a type constructor of any first-order kind taking at least one argument.

Traversable

class (Functor t, Foldable t) => Traversable t

Functors representing data structures that can be traversed from left to right.

Minimal complete definition: traverse or sequenceA.

Instances are similar to Functor, e.g. given a data type

 data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)

a suitable instance would be

 instance Traversable Tree where
    traverse f Empty = pure Empty
    traverse f (Leaf x) = Leaf <$> f x
    traverse f (Node l k r) = Node <$> traverse f l <*> f k <*> traverse f r

This is suitable even for abstract types, as the laws for <*> imply a form of associativity.

The superclass instances should satisfy the following:

  • In the Functor instance, fmap should be equivalent to traversal with the identity applicative functor (fmapDefault).
  • In the Foldable instance, Data.Foldable.foldMap should be equivalent to traversal with a constant applicative functor (foldMapDefault).

makeTraversable :: Name -> Q [Dec]Source

Derive an instance of Traversable for a type constructor of any first-order kind taking at least one argument.

Arbitrary

class ArbitraryF f whereSource

Signature arbitration. An instance ArbitraryF f gives rise to an instance Arbitrary (Term f).

Methods

arbitraryF' :: Arbitrary v => [(Int, Gen (f v))]Source

arbitraryF :: Arbitrary v => Gen (f v)Source

shrinkF :: Arbitrary v => f v -> [f v]Source

Instances

ArbitraryF [] 
ArbitraryF Maybe 
Arbitrary b[13] => ArbitraryF ((,) b[13]) 
ArbitraryF f => ArbitraryF (Context f)

This lifts instances of ArbitraryF to instances of ArbitraryF for the corresponding context functor.

(Arbitrary b[13], Arbitrary c[14]) => ArbitraryF ((,,) b[13] c[14]) 
(ArbitraryF f, Arbitrary p) => ArbitraryF (:&: f p) 
(ArbitraryF f, ArbitraryF g) => ArbitraryF (:+: f g)

Instances of ArbitraryF are closed under forming sums.

(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15]) => ArbitraryF ((,,,) b[13] c[14] d[15]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16]) => ArbitraryF ((,,,,) b[13] c[14] d[15] e[16]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16], Arbitrary f[17]) => ArbitraryF ((,,,,,) b[13] c[14] d[15] e[16] f[17]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16], Arbitrary f[17], Arbitrary g[18]) => ArbitraryF ((,,,,,,) b[13] c[14] d[15] e[16] f[17] g[18]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16], Arbitrary f[17], Arbitrary g[18], Arbitrary h[19]) => ArbitraryF ((,,,,,,,) b[13] c[14] d[15] e[16] f[17] g[18] h[19]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16], Arbitrary f[17], Arbitrary g[18], Arbitrary h[19], Arbitrary i[1a]) => ArbitraryF ((,,,,,,,,) b[13] c[14] d[15] e[16] f[17] g[18] h[19] i[1a]) 
(Arbitrary b[13], Arbitrary c[14], Arbitrary d[15], Arbitrary e[16], Arbitrary f[17], Arbitrary g[18], Arbitrary h[19], Arbitrary i[1a], Arbitrary j[1b]) => ArbitraryF ((,,,,,,,,,) b[13] c[14] d[15] e[16] f[17] g[18] h[19] i[1a] j[1b]) 

makeArbitraryF :: Name -> Q [Dec]Source

Derive an instance of ArbitraryF for a type constructor of any first-order kind taking at least one argument. It is necessary that all types that are used by the data type definition are themselves instances of Arbitrary.

class Arbitrary a where

Random generation and shrinking of values.

Methods

arbitrary :: Gen a

A generator for values of the given type.

shrink :: a -> [a]

Produces a (possibly) empty list of all the possible immediate shrinks of the given value.

Instances

Arbitrary Bool 
Arbitrary Char 
Arbitrary Double 
Arbitrary Float 
Arbitrary Int 
Arbitrary Int8 
Arbitrary Int16 
Arbitrary Int32 
Arbitrary Int64 
Arbitrary Integer 
Arbitrary Word 
Arbitrary Word8 
Arbitrary Word16 
Arbitrary Word32 
Arbitrary Word64 
Arbitrary () 
Arbitrary a => Arbitrary [a] 
(Integral a, Arbitrary a) => Arbitrary (Ratio a) 
(RealFloat a, Arbitrary a) => Arbitrary (Complex a) 
Arbitrary a => Arbitrary (Maybe a) 
ArbitraryF f => Arbitrary (Term f)

This lifts instances of ArbitraryF to instances of Arbitrary for the corresponding term type.

(CoArbitrary a, Arbitrary b) => Arbitrary (a -> b) 
(Arbitrary a, Arbitrary b) => Arbitrary (Either a b) 
(Arbitrary a, Arbitrary b) => Arbitrary (a, b) 
(ArbitraryF f, Arbitrary a) => Arbitrary (Context f a)

This lifts instances of ArbitraryF to instances of Arbitrary for the corresponding context type.

(Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (a, b, c) 
(Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d) => Arbitrary (a, b, c, d) 
(Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e) => Arbitrary (a, b, c, d, e) 

makeArbitrary :: Name -> Q [Dec]Source

Derive an instance of Arbitrary for a type constructor.

class NFData a where

A class of types that can be fully evaluated.

Methods

rnf :: a -> ()

rnf should reduce its argument to normal form (that is, fully evaluate all sub-components), and then return '()'.

The default implementation of rnf is

 rnf a = a `seq` ()

which may be convenient when defining instances for data types with no unevaluated fields (e.g. enumerations).

Instances

NFData Bool 
NFData Char 
NFData Double 
NFData Float 
NFData Int 
NFData Int8 
NFData Int16 
NFData Int32 
NFData Int64 
NFData Integer 
NFData Word 
NFData Word8 
NFData Word16 
NFData Word32 
NFData Word64 
NFData () 
NFData IntSet 
NFData Nothing 
NFData a => NFData [a] 
(Integral a, NFData a) => NFData (Ratio a) 
(RealFloat a, NFData a) => NFData (Complex a) 
NFData a => NFData (Maybe a) 
NFData a => NFData (Tree a) 
NFData a => NFData (IntMap a) 
NFData a => NFData (Set a) 
(NFData a, NFData b) => NFData (Either a b) 
(NFData a, NFData b) => NFData (a, b) 
(Ix a, NFData a, NFData b) => NFData (Array a b) 
(NFData k, NFData a) => NFData (Map k a) 
(NFData a, NFData b, NFData c) => NFData (a, b, c) 
(NFDataF f, NFData a) => NFData (Cxt h f a) 
(NFData a, NFData b, NFData c, NFData d) => NFData (a, b, c, d) 
(NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData (a1, a2, a3, a4, a5) 
(NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => NFData (a1, a2, a3, a4, a5, a6) 
(NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => NFData (a1, a2, a3, a4, a5, a6, a7) 
(NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) => NFData (a1, a2, a3, a4, a5, a6, a7, a8) 
(NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8, NFData a9) => NFData (a1, a2, a3, a4, a5, a6, a7, a8, a9) 

makeNFData :: Name -> Q [Dec]Source

Derive an instance of NFData for a type constructor.

DeepSeq

class NFDataF f whereSource

Signature normal form. An instance NFDataF f gives rise to an instance NFData (Term f).

Methods

rnfF :: NFData a => f a -> ()Source

Instances

NFDataF [] 
NFDataF Maybe 
NFData a[12] => NFDataF ((,) a[12]) 
(NFDataF f, NFDataF g) => NFDataF (:+: f g) 

makeNFDataF :: Name -> Q [Dec]Source

Derive an instance of NFDataF for a type constructor of any first-order kind taking at least one argument.

Smart Constructors

smartConstructors :: Name -> Q [Dec]Source

Derive smart constructors for a type constructor of any first-order kind taking at least one argument. The smart constructors are similar to the ordinary constructors, but an inject is automatically inserted.

Smart Constructors w/ Annotations

smartAConstructors :: Name -> Q [Dec]Source

Derive smart constructors with products for a type constructor of any parametric kind taking at least one argument. The smart constructors are similar to the ordinary constructors, but an injectA is automatically inserted.

Lifting to Sums

liftSum :: Name -> Q [Dec]Source

Given the name of a type class, where the first parameter is a functor, lift it to sums of functors. Example: class ShowF f where ... is lifted as instance (ShowF f, ShowF g) => ShowF (f :+: g) where ... .

caseF :: (f a -> b) -> (g a -> b) -> (f :+: g) a -> bSource

Utility function to case on a functor sum, without exposing the internal representation of sums.