Portability | non-portable |
---|---|

Stability | experimental |

Maintainer | sjoerd@w3future.com |

Safe Haskell | None |

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

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

type class.

Here's an example how to write such an instance for this data type:

data T a = A Int a | B a (T a)

instance`ADT`

(T a) where`ctorIndex`

A{} = 0`ctorIndex`

B{} = 1 type`Constraints`

(T a) c = (c Int, c a, c (T a))`buildsRecA`

`For`

sub rec = [ (`ctor`

"A", A`<$>`

sub (`FieldInfo`

(\(A i _) -> i))`<*>`

sub (`FieldInfo`

(\(A _ a) -> a))) , (`ctor`

"B", B`<$>`

sub (`FieldInfo`

(\(B a _) -> a))`<*>`

rec (`FieldInfo`

(\(B _ t) -> t))) ]

And this is how you would write generic equality, using the `All`

monoid:

eqADT :: (`ADT`

t,`Constraints`

t`Eq`

) => t -> t ->`Bool`

eqADT s t =`ctorIndex`

s ==`ctorIndex`

t`&&`

`getAll`

(`mbuilds`

(`For`

::`For`

`Eq`

) (\fld ->`All`

$ s`!`

fld`==`

t`!`

fld) ``at`

` s)

- module Generics.OneLiner.Info
- data Constraint
- class ADT t where
- type Constraints t c :: Constraint
- ctorIndex :: t -> Int
- buildsA :: (Constraints t c, Applicative f) => For c -> (forall s. c s => FieldInfo (t -> s) -> f s) -> [(CtorInfo, f t)]
- buildsRecA :: (Constraints t c, Applicative f) => For c -> (forall s. c s => FieldInfo (t -> s) -> f s) -> (FieldInfo (t -> t) -> f t) -> [(CtorInfo, f t)]

- data For c = For
- (!) :: t -> FieldInfo (t -> s) -> s
- at :: ADT t => [(a, b)] -> t -> b
- builds :: (ADT t, Constraints t c) => For c -> (forall s. c s => FieldInfo (t -> s) -> s) -> [(CtorInfo, t)]
- mbuilds :: forall t c m. (ADT t, Constraints t c, Monoid m) => For c -> (forall s. c s => FieldInfo (t -> s) -> m) -> [(CtorInfo, m)]
- 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

# Re-exports

module Generics.OneLiner.Info

data Constraint

The kind of constraints

# The `ADT`

type class

Type class for algebraic data types of kind `*`

. Minimal implementation: `ctorIndex`

and either `buildsA`

if the type `t`

is not recursive, or `buildsRecA`

if the type `t`

is recursive.

type Constraints t c :: ConstraintSource

The constraints needed to run `buildsA`

and `buildsRecA`

.
It should be a list of all the types of the subcomponents of `t`

, each applied to `c`

.

Gives the index of the constructor of the given value in the list returned by `buildsA`

and `buildsRecA`

.

:: (Constraints t c, Applicative f) | |

=> For c | Witness for the constraint |

-> (forall s. c s => FieldInfo (t -> s) -> f s) | This function should return a value
for each subcomponent of |

-> [(CtorInfo, f t)] | A list of pairs, one for each constructor of type |

:: (Constraints t c, Applicative f) | |

=> For c | Witness for the constraint |

-> (forall s. c s => FieldInfo (t -> s) -> f s) | This function should return a value
for each subcomponent of |

-> (FieldInfo (t -> t) -> f t) | This function should return a value
for each subcomponent of |

-> [(CtorInfo, f t)] | A list of pairs, one for each constructor of type |

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.

# Helper functions

(!) :: t -> FieldInfo (t -> s) -> sSource

Get the subcomponent by using the projector from the field information.

at :: ADT t => [(a, b)] -> t -> bSource

Get the value from the result of one of the `builds`

functions that matches the constructor of `t`

.

# Derived traversal schemes

builds :: (ADT t, Constraints t c) => For c -> (forall s. c s => FieldInfo (t -> s) -> s) -> [(CtorInfo, t)]Source

mbuilds :: forall t c m. (ADT t, Constraints t c, Monoid m) => For c -> (forall s. c s => FieldInfo (t -> s) -> m) -> [(CtorInfo, m)]Source

gmap :: (ADT t, Constraints t c) => For c -> (forall s. c s => s -> s) -> t -> tSource

Transform a value by transforming each subcomponent.

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

Fold a value, by mapping each subcomponent to a monoid value and collecting those.

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

Applicative traversal given a way to traverse each subcomponent.