| Copyright | (c) 2010-2011 Patrick Bahr | 
|---|---|
| License | BSD3 | 
| Maintainer | Patrick Bahr <paba@diku.dk> | 
| Stability | experimental | 
| Portability | non-portable (GHC Extensions) | 
| Safe Haskell | None | 
| Language | Haskell98 | 
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.
- derive :: [Name -> Q [Dec]] -> [Name] -> Q [Dec]
 - class ShowF f where
 - makeShowF :: Name -> Q [Dec]
 - class ShowConstr f where
 - makeShowConstr :: Name -> Q [Dec]
 - class EqF f where
 - makeEqF :: Name -> Q [Dec]
 - class EqF f => OrdF f where
 - makeOrdF :: Name -> Q [Dec]
 - class Foldable t
 - makeFoldable :: Name -> Q [Dec]
 - class (Functor t, Foldable t) => Traversable t
 - makeTraversable :: Name -> Q [Dec]
 - makeHaskellStrict :: Name -> Q [Dec]
 - haskellStrict :: (Monad m, HaskellStrict f, f :<: (m :+: g)) => f (TermT m g) -> TermT m g
 - haskellStrict' :: (Monad m, HaskellStrict f, f :<: (m :+: g)) => f (TermT m g) -> TermT m g
 - class ArbitraryF f where
 - makeArbitraryF :: Name -> Q [Dec]
 - class Arbitrary a where
 - makeArbitrary :: Name -> Q [Dec]
 - class NFData a where
 - makeNFData :: Name -> Q [Dec]
 - class NFDataF f where
 - makeNFDataF :: Name -> Q [Dec]
 - smartConstructors :: Name -> Q [Dec]
 - smartAConstructors :: Name -> Q [Dec]
 - liftSum :: Name -> Q [Dec]
 
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
Signature printing. An instance ShowF f gives rise to an instance
  Show (Term f). 
Minimal complete definition
makeShowF :: Name -> Q [Dec] Source #
Derive an instance of ShowF for a type constructor of any first-order kind
  taking at least one argument. 
class ShowConstr f where Source #
Constructor printing.
Minimal complete definition
Methods
showConstr :: f a -> String Source #
makeShowConstr :: Name -> Q [Dec] Source #
Derive an instance of showConstr for a type constructor of any first-order kind
  taking at least one argument. 
EqF
Signature equality. An instance EqF f gives rise to an instance
  Eq (Term f). 
Minimal complete definition
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 where Source #
Signature ordering. An instance OrdF f gives rise to an instance
  Ord (Term f). 
Minimal complete definition
makeOrdF :: Name -> Q [Dec] Source #
Derive an instance of OrdF for a type constructor of any first-order kind
  taking at least one argument. 
Foldable
Data structures that can be folded.
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
Foldable instances are expected to satisfy the following laws:
foldr f z t = appEndo (foldMap (Endo . f) t ) z
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
fold = foldMap id
sum, product, maximum, and minimum should all be essentially
 equivalent to foldMap forms, such as
sum = getSum . foldMap Sum
but may be less defined.
If the type is also a Functor instance, it should satisfy
foldMap f = fold . fmap f
which implies that
foldMap f . fmap g = foldMap (f . g)
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.
A definition of traverse must satisfy the following laws:
- naturality
 t .for every applicative transformationtraversef =traverse(t . f)t- identity
 traverseIdentity = Identity- composition
 traverse(Compose .fmapg . f) = Compose .fmap(traverseg) .traversef
A definition of sequenceA must satisfy the following laws:
- naturality
 t .for every applicative transformationsequenceA=sequenceA.fmaptt- identity
 sequenceA.fmapIdentity = Identity- composition
 sequenceA.fmapCompose = Compose .fmapsequenceA.sequenceA
where an applicative transformation is a function
t :: (Applicative f, Applicative g) => f a -> g a
preserving the Applicative operations, i.e.
and the identity functor Identity and composition of functors Compose
 are defined as
  newtype Identity a = Identity a
  instance Functor Identity where
    fmap f (Identity x) = Identity (f x)
  instance Applicative Identity where
    pure x = Identity x
    Identity f <*> Identity x = Identity (f x)
  newtype Compose f g a = Compose (f (g a))
  instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose x) = Compose (fmap (fmap f) x)
  instance (Applicative f, Applicative g) => Applicative (Compose f g) where
    pure x = Compose (pure (pure x))
    Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)(The naturality law is implied by parametricity.)
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 
Functorinstance,fmapshould be equivalent to traversal with the identity applicative functor (fmapDefault). - In the 
Foldableinstance,foldMapshould be equivalent to traversal with a constant applicative functor (foldMapDefault). 
Instances
makeTraversable :: Name -> Q [Dec] Source #
Derive an instance of Traversable for a type constructor of any
  first-order kind taking at least one argument. 
HaskellStrict
makeHaskellStrict :: Name -> Q [Dec] Source #
Derive an instance of HaskellStrict for a type constructor of any
  first-order kind taking at least one argument. 
haskellStrict' :: (Monad m, HaskellStrict f, f :<: (m :+: g)) => f (TermT m g) -> TermT m g Source #
Arbitrary
class ArbitraryF f where Source #
Signature arbitration. An instance ArbitraryF f gives rise to an instance
  Arbitrary (Term f). 
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. 
Random generation and shrinking of values.
Minimal complete definition
Methods
A generator for values of the given type.
Produces a (possibly) empty list of all the possible immediate shrinks of the given value. The default implementation returns the empty list, so will not try to shrink the value.
Most implementations of shrink should try at least three things:
- Shrink a term to any of its immediate subterms.
 - Recursively apply 
shrinkto all immediate subterms. - Type-specific shrinkings such as replacing a constructor by a simpler constructor.
 
For example, suppose we have the following implementation of binary trees:
data Tree a = Nil | Branch a (Tree a) (Tree a)
We can then define shrink as follows:
shrink Nil = [] shrink (Branch x l r) = -- shrink Branch to Nil [Nil] ++ -- shrink to subterms [l, r] ++ -- recursively shrink subterms [Branch x' l' r' | (x', l', r') <- shrink (x, l, r)]
There are a couple of subtleties here:
- QuickCheck tries the shrinking candidates in the order they
   appear in the list, so we put more aggressive shrinking steps
   (such as replacing the whole tree by 
Nil) before smaller ones (such as recursively shrinking the subtrees). - It is tempting to write the last line as
   
[Branch x' l' r' | x' <- shrink x, l' <- shrink l, r' <- shrink r]but this is the wrong thing! It will force QuickCheck to shrinkx,landrin tandem, and shrinking will stop once one of the three is fully shrunk. 
There is a fair bit of boilerplate in the code above.
 We can avoid it with the help of some generic functions;
 note that these only work on GHC 7.2 and above.
 The function genericShrink tries shrinking a term to all of its
 subterms and, failing that, recursively shrinks the subterms.
 Using it, we can define shrink as:
shrink x = shrinkToNil x ++ genericShrink x
  where
    shrinkToNil Nil = []
    shrinkToNil (Branch _ l r) = [Nil]genericShrink is a combination of subterms, which shrinks
 a term to any of its subterms, and recursivelyShrink, which shrinks
 all subterms of a term. These may be useful if you need a bit more
 control over shrinking than genericShrink gives you.
A final gotcha: we cannot define shrink as simply 
 as this shrinks shrink x = Nil:genericShrink xNil to Nil, and shrinking will go into an
 infinite loop.
If all this leaves you bewildered, you might try  to begin with,
 after deriving shrink = genericShrinkGeneric for your type. However, if your data type has any
 special invariants, you will need to check that genericShrink can't break those invariants.
Instances
A class of types that can be fully evaluated.
Since: 1.1.0.0
Methods
rnf should reduce its argument to normal form (that is, fully
 evaluate all sub-components), and then return '()'.
Generic NFData deriving
Starting with GHC 7.2, you can automatically derive instances
 for types possessing a Generic instance.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic)
import Control.DeepSeq
data Foo a = Foo a String
             deriving (Eq, Generic)
instance NFData a => NFData (Foo a)
data Colour = Red | Green | Blue
              deriving Generic
instance NFData ColourStarting with GHC 7.10, the example above can be written more
 concisely by enabling the new DeriveAnyClass extension:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics (Generic)
import Control.DeepSeq
data Foo a = Foo a String
             deriving (Eq, Generic, NFData)
data Colour = Red | Green | Blue
              deriving (Generic, NFData)
Compatibility with previous deepseq versions
Prior to version 1.4.0.0, the default implementation of the rnf
 method was defined as
rnfa =seqa ()
However, starting with deepseq-1.4.0.0, the default
 implementation is based on DefaultSignatures allowing for
 more accurate auto-derived NFData instances. If you need the
 previously used exact default rnf method implementation
 semantics, use
instance NFData Colour where rnf x = seq x ()
or alternatively
{-# LANGUAGE BangPatterns #-}
instance NFData Colour where rnf !_ = ()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 CallStack | Since: 1.4.2.0  | 
| NFData TypeRep | NOTE: Only defined for  Since: 1.4.0.0  | 
| NFData () | |
| NFData TyCon | NOTE: Only defined for  Since: 1.4.0.0  | 
| NFData Natural | Since: 1.4.0.0  | 
| NFData Void | Since: 1.4.0.0  | 
| NFData Version | Since: 1.3.0.0  | 
| NFData Unique | Since: 1.4.0.0  | 
| NFData ThreadId | Since: 1.4.0.0  | 
| NFData ExitCode | Since: 1.4.2.0  | 
| NFData CChar | Since: 1.4.0.0  | 
| NFData CSChar | Since: 1.4.0.0  | 
| NFData CUChar | Since: 1.4.0.0  | 
| NFData CShort | Since: 1.4.0.0  | 
| NFData CUShort | Since: 1.4.0.0  | 
| NFData CInt | Since: 1.4.0.0  | 
| NFData CUInt | Since: 1.4.0.0  | 
| NFData CLong | Since: 1.4.0.0  | 
| NFData CULong | Since: 1.4.0.0  | 
| NFData CLLong | Since: 1.4.0.0  | 
| NFData CULLong | Since: 1.4.0.0  | 
| NFData CFloat | Since: 1.4.0.0  | 
| NFData CDouble | Since: 1.4.0.0  | 
| NFData CPtrdiff | Since: 1.4.0.0  | 
| NFData CSize | Since: 1.4.0.0  | 
| NFData CWchar | Since: 1.4.0.0  | 
| NFData CSigAtomic | Since: 1.4.0.0  | 
| NFData CClock | Since: 1.4.0.0  | 
| NFData CTime | Since: 1.4.0.0  | 
| NFData CUSeconds | Since: 1.4.0.0  | 
| NFData CSUSeconds | Since: 1.4.0.0  | 
| NFData CFile | Since: 1.4.0.0  | 
| NFData CFpos | Since: 1.4.0.0  | 
| NFData CJmpBuf | Since: 1.4.0.0  | 
| NFData CIntPtr | Since: 1.4.0.0  | 
| NFData CUIntPtr | Since: 1.4.0.0  | 
| NFData CIntMax | Since: 1.4.0.0  | 
| NFData CUIntMax | Since: 1.4.0.0  | 
| NFData All | Since: 1.4.0.0  | 
| NFData Any | Since: 1.4.0.0  | 
| NFData Fingerprint | Since: 1.4.0.0  | 
| NFData SrcLoc | Since: 1.4.2.0  | 
| NFData IntSet | |
| NFData Doc | |
| NFData TextDetails | |
| NFData LocalTime | |
| NFData ZonedTime | |
| NFData a => NFData [a] | |
| NFData a => NFData (Maybe a) | |
| NFData a => NFData (Ratio a) | |
| NFData (Ptr a) | Since: 1.4.2.0  | 
| NFData (FunPtr a) | Since: 1.4.2.0  | 
| NFData a => NFData (Identity a) | Since: 1.4.0.0  | 
| NFData a => NFData (Min a) | Since: 1.4.2.0  | 
| NFData a => NFData (Max a) | Since: 1.4.2.0  | 
| NFData a => NFData (First a) | Since: 1.4.2.0  | 
| NFData a => NFData (Last a) | Since: 1.4.2.0  | 
| NFData m => NFData (WrappedMonoid m) | Since: 1.4.2.0  | 
| NFData a => NFData (Option a) | Since: 1.4.2.0  | 
| NFData a => NFData (NonEmpty a) | Since: 1.4.2.0  | 
| NFData (Fixed a) | Since: 1.3.0.0  | 
| NFData a => NFData (Complex a) | |
| NFData (StableName a) | Since: 1.4.0.0  | 
| NFData a => NFData (ZipList a) | Since: 1.4.0.0  | 
| NFData a => NFData (Dual a) | Since: 1.4.0.0  | 
| NFData a => NFData (Sum a) | Since: 1.4.0.0  | 
| NFData a => NFData (Product a) | Since: 1.4.0.0  | 
| NFData a => NFData (First a) | Since: 1.4.0.0  | 
| NFData a => NFData (Last a) | Since: 1.4.0.0  | 
| NFData (IORef a) | NOTE: Only strict in the reference and not the referenced value. Since: 1.4.2.0  | 
| NFData a => NFData (Down a) | Since: 1.4.0.0  | 
| NFData (MVar a) | NOTE: Only strict in the reference and not the referenced value. Since: 1.4.2.0  | 
| NFData a => NFData (Digit a) | |
| NFData a => NFData (Node a) | |
| NFData a => NFData (Elem a) | |
| NFData a => NFData (FingerTree a) | |
| NFData a => NFData (IntMap a) | |
| NFData a => NFData (Tree a) | |
| NFData a => NFData (Seq a) | |
| NFData a => NFData (Set a) | |
| NFData a => NFData (Doc a) | |
| NFData a => NFData (AnnotDetails a) | |
| NFData a => NFData (HashSet a) | |
| NFData (a -> b) | This instance is for convenience and consistency with  Since: 1.3.0.0  | 
| (NFData a, NFData b) => NFData (Either a b) | |
| (NFData a, NFData b) => NFData (a, b) | |
| (NFData a, NFData b) => NFData (Array a b) | |
| (NFData a, NFData b) => NFData (Arg a b) | Since: 1.4.2.0  | 
| NFData (Proxy k a) | Since: 1.4.0.0  | 
| NFData (STRef s a) | NOTE: Only strict in the reference and not the referenced value. Since: 1.4.2.0  | 
| (NFData k, NFData a) => NFData (Map k a) | |
| (NFData k, NFData v) => NFData (Leaf k v) | |
| (NFData k, NFData v) => NFData (HashMap k v) | |
| (NFData a, NFData b, NFData c) => NFData (a, b, c) | |
| NFData a => NFData (Const k a b) | Since: 1.4.0.0  | 
| (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) | |
DeepSeq
class NFDataF f where Source #
Signature normal form. An instance NFDataF f gives rise to an instance
  NFData (Term f). 
Minimal complete definition
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.