License | BSD-style (see the file LICENSE) |
---|---|

Maintainer | sjoerd@w3future.com |

Stability | experimental |

Portability | non-portable |

Safe Haskell | None |

Language | Haskell98 |

This module is for writing generic functions on algebraic data types
of kind `*`

. These data types must be an instance of the `Generic`

type
class, which can be derived.

- create :: (ADT t, Constraints t c) => for c -> (forall s. c s => s) -> [t]
- createA :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => f s) -> [f t]
- ctorIndex :: ADT t => t -> Int
- gmap :: (ADT t, Constraints t c) => for c -> (forall s. c s => s -> s) -> t -> t
- gfoldMap :: (ADT t, Constraints t c, Monoid m) => for c -> (forall s. c s => s -> m) -> t -> m
- gtraverse :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => s -> f s) -> t -> f t
- gzipWith :: (ADT t, Constraints t c) => for c -> (forall s. c s => s -> s -> s) -> t -> t -> Maybe t
- mzipWith :: (ADT t, Constraints t c, Monoid m) => for c -> (forall s. c s => s -> s -> m) -> t -> t -> m
- zipWithA :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => s -> s -> f s) -> t -> t -> Maybe (f t)
- consume :: (ADT t, Constraints t c, Decidable f) => for c -> (forall s. c s => f s) -> f t
- op0 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s) -> t
- op1 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s) -> t -> t
- op2 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s -> s) -> t -> t -> t
- type ADT t = (Generic t, ADT' (Rep t))
- type ADTRecord t = (ADT t, 1 ~ CtorCount t)
- type ADTNonEmpty t = (ADT t, 1 <= CtorCount t)
- type CtorCount t = CtorCount' (Rep t)
- type Constraints t c = Constraints' (Rep t) c
- data For c = For
- class DeepConstraint c t => Deep c t
- type family DeepConstraint c t :: Constraint
- isAtom :: forall t proxy. (ADT t, Typeable t, Constraints t Typeable) => proxy t -> Bool

# Producing values

create :: (ADT t, Constraints t c) => for c -> (forall s. c s => s) -> [t] Source

createA :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => f s) -> [f t] Source

ctorIndex :: ADT t => t -> Int Source

Get the index in the lists returned by `create`

and `createA`

of the constructor of the given value.

For example, this is the implementation of `put`

that generates the binary data that
the above implentation of `get`

expects:

`put`

t =`putWord8`

(`toEnum`

(`ctorIndex`

t))`<>`

`gfoldMap`

(`For`

::`For`

`Binary`

)`put`

t

*Note that this assumes a straightforward Monoid instance of Put which binary unfortunately does not provide.*

# Traversing values

gmap :: (ADT t, Constraints t c) => for c -> (forall s. c s => s -> s) -> t -> t Source

Map over a structure, updating each component.

gfoldMap :: (ADT t, Constraints t c, Monoid m) => for c -> (forall s. c s => s -> m) -> t -> m Source

gtraverse :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => s -> f s) -> t -> f t Source

Map each component of a structure to an action, evaluate these actions from left to right, and collect the results.

# Combining values

gzipWith :: (ADT t, Constraints t c) => for c -> (forall s. c s => s -> s -> s) -> t -> t -> Maybe t Source

Combine two values by combining each component of the structures with the given function.
Returns `Nothing`

if the constructors don't match.

mzipWith :: (ADT t, Constraints t c, Monoid m) => for c -> (forall s. c s => s -> s -> m) -> t -> t -> m Source

zipWithA :: (ADT t, Constraints t c, Applicative f) => for c -> (forall s. c s => s -> s -> f s) -> t -> t -> Maybe (f t) Source

Combine two values by combining each component of the structures with the given function, under an applicative effect.
Returns `Nothing`

if the constructors don't match.

# Consuming values

consume :: (ADT t, Constraints t c, Decidable f) => for c -> (forall s. c s => f s) -> f t Source

Generate ways to consume values of type `t`

. This is the contravariant version of `createA`

.

# Single constructor functions

op0 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s) -> t Source

op1 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s) -> t -> t Source

op2 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s -> s) -> t -> t -> t Source

# Types

type ADTNonEmpty t = (ADT t, 1 <= CtorCount t) Source

`ADTNonEmpty`

is a constraint type synonym. An instance is an `ADT`

with *at least* one constructor.

type Constraints t c = Constraints' (Rep t) c Source

`Constraints`

is a constraint type synonym, containing the constraint requirements for an instance for `t`

of class `c`

.
It requires an instance of class `c`

for each component of `t`

.

Tell the compiler which class we want to use in the traversal. Should be used like this:

(For :: For Show)

Where `Show`

can be any class.

class DeepConstraint c t => Deep c t Source

`Deep c`

recursively requires all parts of the datatype to be an instance of `c`

and of `Generic`

.

DeepConstraint c t => Deep c t |

type family DeepConstraint c t :: Constraint Source

A trick to avoid GHC from detecting a cycle.

type DeepConstraint c t = (c t, ADT t, Constraints t (Deep c), Constraints t c) |