| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Transformation
Description
A natural transformation is a concept from category theory for a mapping between two functors and their objects
that preserves a naturality condition. In Haskell the naturality condition boils down to parametricity, so a
natural transformation between two functors f and g is represented as
type NaturalTransformation f g = ∀a. f a → g a
This type appears in several Haskell libraries, most obviously in
natural-transformations. There are times, however,
when we crave more control. Sometimes what we want to do depends on which type a is hiding in that f a we're
given. Sometimes, in other words, we need an unnatural transformation.
This means we have to abandon parametricity for ad-hoc polymorphism, and that means type classes. There are two steps to defining a transformation:
- an instance of the base class
Transformationdeclares the two functors being mapped, much like a function type signature, - while the actual mapping of values is performed by an arbitrary number of instances of the method
$, a bit like multiple equation clauses that make up a single function definition.
The module is meant to be imported qualified, and the importing module will require at least the
FlexibleInstances, MultiParamTypeClasses, and TypeFamilies language extensions to declare the appropriate
instances.
Synopsis
- class Transformation t where
- class Transformation t => At t x where
- apply :: At t x => t -> Domain t x -> Codomain t x
- data Coercion (p :: Type -> Type) (q :: Type -> Type) = Coercion
- data Compose t u = Compose t u
- newtype Mapped (f :: Type -> Type) t = Mapped t
- newtype Folded (f :: Type -> Type) t = Folded t
- newtype Traversed (f :: Type -> Type) t = Traversed t
- type family ComposeOuter (c :: Type -> Type) :: Type -> Type where ...
- type family ComposeInner (c :: Type -> Type) :: Type -> Type where ...
Documentation
>>>:seti -XFlexibleInstances -XMultiParamTypeClasses -XTypeFamilies -XTypeOperators>>>import Transformation (Transformation)>>>import qualified Transformation>>>data MaybeToList = MaybeToList>>>instance Transformation MaybeToList where {type Domain MaybeToList = Maybe; type Codomain MaybeToList = []}
class Transformation t Source #
A Transformation, natural or not, maps one functor to another.
For example, here's the declaration for a transformation that maps Maybe to `[]`:
data MaybeToList = MaybeToList instance Transformation MaybeToList where type Domain MaybeToList = Maybe type Codomain MaybeToList = []
Instances
class Transformation t => At t x where Source #
Before we can apply a Transformation, we also need to declare At which base types it is applicable and how
it works. If the transformation is natural, we'll need only one instance declaration.
>>>:{instance MaybeToList `Transformation.At` a where MaybeToList $ Just x = [x] MaybeToList $ Nothing = [] :}
>>>MaybeToList Transformation.$ (Just True)[True]
An unnatural Transformation can behave differently depending on the base type and even on its value.
>>>:{instance {-# OVERLAPS #-} MaybeToList `At` Char where MaybeToList $ Just '\0' = [] MaybeToList $ Just c = [c] MaybeToList $ Nothing = [] :}
Methods
Instances
| (At t g, Apply (g sem), Traversable (g sem), sem ~ Semantics t) => At (Knit t) (g sem sem) Source # | |
| (Attribution t, p ~ Origin t, a ~ Inherited t, b ~ Synthesized t, q ~ Semantics a b, Foldable (g q), Functor (g q), Monoid a, Monoid b, Foldable p, At t g) => At (T t) (g (Semantics a b) (Semantics a b)) Source # | |
| (Transformation (Auto t), p ~ Domain (Auto t), q ~ Codomain (Auto t), q ~ Semantics a, a ~ Attributes (Auto t), Foldable (g q), Monoid a, Foldable p, Attribution (Auto t) g) => At (Auto t) (g (Semantics a) (Semantics a)) Source # | |
| (At t x, At u x, Domain t ~ Domain u) => At (Either t u) x Source # | |
| Coercible (p x) (q x) => At (Coercion p q) x Source # | |
| (At t x, At u x, Domain t ~ Codomain u) => At (Compose t u) x Source # | |
| (At t x, Foldable f, Codomain t ~ (Const m :: Type -> Type), Monoid m) => At (Folded f t) x Source # | |
| (At t x, Functor f) => At (Mapped f t) x Source # | |
| (At t x, Traversable f, Codomain t ~ Compose m n, Applicative m) => At (Traversed f t) x Source # | |
| At (Fold p m) x Source # | |
| At (Map p q) x Source # | |
| (At t x, At u x, Domain t ~ Domain u) => At (t, u) x Source # | |
| At (Traversal p q m) x Source # | |
| At (Arrow p q x) x Source # | |
data Coercion (p :: Type -> Type) (q :: Type -> Type) Source #
Transformation that coerces a p x to q x
Constructors
| Coercion |
Instances
| Transformation (Coercion p q) Source # | |||||||||
Defined in Transformation Associated Types
| |||||||||
| Coercible (p x) (q x) => At (Coercion p q) x Source # | |||||||||
| type Codomain (Coercion p q) Source # | |||||||||
Defined in Transformation | |||||||||
| type Domain (Coercion p q) Source # | |||||||||
Defined in Transformation | |||||||||
Composition of two transformations
Constructors
| Compose t u |
Instances
| (Transformation t, Transformation u, Domain t ~ Codomain u) => Transformation (Compose t u) Source # | |
Defined in Transformation | |
| (At t x, At u x, Domain t ~ Codomain u) => At (Compose t u) x Source # | |
| type Codomain (Compose t u) Source # | |
Defined in Transformation | |
| type Domain (Compose t u) Source # | |
Defined in Transformation | |
newtype Mapped (f :: Type -> Type) t Source #
Transformation under a Functor
Constructors
| Mapped t |
Instances
| Transformation t => Transformation (Mapped f t) Source # | |
Defined in Transformation | |
| (At t x, Functor f) => At (Mapped f t) x Source # | |
| type Codomain (Mapped f t) Source # | |
Defined in Transformation | |
| type Domain (Mapped f t) Source # | |
Defined in Transformation | |
newtype Folded (f :: Type -> Type) t Source #
Transformation under a Foldable
Constructors
| Folded t |
Instances
| Transformation t => Transformation (Folded f t) Source # | |
Defined in Transformation | |
| (At t x, Foldable f, Codomain t ~ (Const m :: Type -> Type), Monoid m) => At (Folded f t) x Source # | |
| type Codomain (Folded f t) Source # | |
Defined in Transformation | |
| type Domain (Folded f t) Source # | |
Defined in Transformation | |
newtype Traversed (f :: Type -> Type) t Source #
Transformation under a Traversable
Constructors
| Traversed t |
Instances
| (Transformation t, Codomain t ~ Compose m n) => Transformation (Traversed f t) Source # | |||||||||
Defined in Transformation Associated Types
| |||||||||
| (At t x, Traversable f, Codomain t ~ Compose m n, Applicative m) => At (Traversed f t) x Source # | |||||||||
| type Codomain (Traversed f t) Source # | |||||||||
Defined in Transformation type Codomain (Traversed f t) = Compose (ComposeOuter (Codomain t)) (Compose f (ComposeInner (Codomain t))) | |||||||||
| type Domain (Traversed f t) Source # | |||||||||
Defined in Transformation | |||||||||
type family ComposeOuter (c :: Type -> Type) :: Type -> Type where ... Source #
Equations
| ComposeOuter (Compose p q) = p |
type family ComposeInner (c :: Type -> Type) :: Type -> Type where ... Source #
Equations
| ComposeInner (Compose p q) = q |