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)
instanceADT
(T a) wherectorIndex
A{} = 0ctorIndex
B{} = 1 typeConstraints
(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
tEq
) => 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.