Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
- class NFunctor f where
- type VarianceStack f :: k -> k -> *
- class VarianceTransformer t a where
- newtype CovariantT to f f' = CovariantT {
- (<#>) :: forall a a'. (a -> a') -> f a `to` f' a'
- newtype Covariant1T to f f' = Covariant1T {}
- newtype ContravariantT to f f' = ContravariantT {
- (>#<) :: forall a a'. (a' -> a) -> f a `to` f' a'
- newtype Contravariant1T to f f' = Contravariant1T {}
- newtype InvariantT to f f' = InvariantT {
- (<#>/>#<) :: forall a a'. (a -> a', a' -> a) -> f a `to` f' a'
- newtype Invariant1T to f f' = Invariant1T {
- (<##>/>##<) :: forall m m'. (Functor m, Functor m') => (m :~> m', m' :~> m) -> f m `to` f' m'
- newtype NonvariantT to f f' = NonvariantT {
- unNonvariant :: forall a a'. a ~ a' => f a `to` f' a'
- newtype PhantomvariantT to f f' = PhantomvariantT {
- (👻#👻) :: forall a a'. () -> f a `to` f' a'
Documentation
class NFunctor f where Source #
A generalization of Functor
, Bifunctor
, Contravariant
, Profunctor
, etc.
(NFunctor f, VarianceStack f ~ CovariantT (->)
is equivalent toFunctor f
.(NFunctor f, VarianceStack f ~ CovariantT (CovariantT (->))
is equivalent toBifunctor f
.(NFunctor f, VarianceStack f ~ ContravariantT (->)
is equivalent toContravariant f
.(NFunctor f, VarianceStack f ~ InvariantT (->)
is equivalent toInvariant f
.(NFunctor f, VarianceStack f ~ ContravariantT (CovariantT (->))
is equivalent toProfunctor f
.
The associated type VarianceStack
specifies the variance of all the type
parameters using a stack of VarianceTransformer
s ending with (->)
.
Example instance:
instance NFunctor (,,) where type VarianceStack (,,) = CovariantT (CovariantT (CovariantT (->))) nmap = CovariantT $ \f1 -> CovariantT $ \f2 -> CovariantT $ \f3 -> \(x1,x2,x3) -> (f1 x1, f2 x2, f3 x3)
Note that it is not possible to write an instance for a partially-applied
type; for example, it is not possible to write an NFunctor ((,,) a)
instance corresponding to the Functor ((,,) a)
instance. Instead, the
NFunctor ((,,) a)
and NFunctor ((,,) a b)
instances are derived from the
above instance.
Laws:
nmap <#> id = nmap -#- () = id nmap >#< id = nmap -#- () = id nmap <#>/>#< (id, id) = nmap -#- () = id ...
nmap -#- () -#- () <#> f = nmap -#- () <#> f = nmap <#> f
(nmap <#> f1 <#> f2) . (nmap <#> g1 <#> g2) = nmap <#> (f1 . g1) <#> (f2 . g2) (nmap >#< f1 >#< f2) . (nmap >#< g1 >#< g2) = nmap >#< (g1 . f1) >#< (g2 . f2) ...
type VarianceStack f :: k -> k -> * Source #
nmap :: VarianceStack f f f Source #
(NFunctor (k1 -> k) f, (~) ((k1 -> k) -> (k1 -> k) -> *) (VarianceStack (k1 -> k) f) (t inner), VarianceTransformer k1 k t a) => NFunctor k (f a) Source # | A bold instance! We should be suspicious of any instance for I claim that you will never have to write such an instance; it will always
be possible to write the |
NFunctor * () Source # | For kind
|
NFunctor (* -> (* -> *) -> * -> *) WriterT Source # | |
NFunctor (* -> (* -> *) -> * -> *) StateT Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> * -> *) (,,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> * -> *) (,,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> * -> *) (,,,,,) Source # | |
NFunctor (* -> * -> * -> * -> * -> *) (,,,,) Source # | |
NFunctor (* -> * -> * -> * -> *) (,,,) Source # | |
NFunctor (* -> * -> * -> *) (,,) Source # | |
NFunctor (* -> * -> *) (->) Source # | |
NFunctor (* -> * -> *) Either Source # | |
NFunctor (* -> * -> *) (,) Source # | |
NFunctor (* -> *) Identity Source # | |
NFunctor (* -> k -> *) (Const k) Source # | |
NFunctor (* -> (* -> *) -> * -> *) (ReaderT *) Source # | |
class VarianceTransformer t a where Source #
This library uses a stack of VarianceTransformer
s to indicate the variance
of each type parameter. Each transformer in the stack specifies the variance
of one type parameter, and wraps an inner stack specifying the variance of
the remaining type parameters, until we reach (->)
, the base of the stack.
Each VarianceTransformer
is eliminated by an infix function, such as
(<#>)
. This function takes a stack on the left, and its second argument
has whatever type is necessary in order to map over the corresponding
type parameter; for covariant type parameters, it will be a function of type
(a -> b)
, for contravariant type parameters, it will be a function of
type (b -> a)
, for invariant type parameters, it will be a pair of
functions (a -> b, b -> a)
, etc.
The (-#-)
method witnesses the fact that regardless of the variance of a
given type parameter, there is always an identity-like argument which can be
passed as that second argument which will cause that type parameter to be
left unchanged. It takes a stack on the left, and its second argument is
simply ()
.
VarianceTransformer k1 k (NonvariantT k1 k k) a Source # | |
VarianceTransformer k1 k (PhantomvariantT k1 k1 k k) a Source # | |
VarianceTransformer * k (InvariantT k k) a Source # | |
VarianceTransformer * k (ContravariantT k k) a Source # | |
VarianceTransformer * k (CovariantT k k) a Source # | |
Functor m => VarianceTransformer (* -> *) k (Invariant1T k k) m Source # | |
Functor m => VarianceTransformer (* -> *) k (Contravariant1T k k) m Source # | |
Functor m => VarianceTransformer (* -> *) k (Covariant1T k k) m Source # | |
newtype CovariantT to f f' Source #
CovariantT | |
|
VarianceTransformer * k (CovariantT k k) a Source # | |
newtype Covariant1T to f f' Source #
Functor m => VarianceTransformer (* -> *) k (Covariant1T k k) m Source # | |
newtype ContravariantT to f f' Source #
ContravariantT | |
|
VarianceTransformer * k (ContravariantT k k) a Source # | |
newtype Contravariant1T to f f' Source #
Functor m => VarianceTransformer (* -> *) k (Contravariant1T k k) m Source # | |
newtype InvariantT to f f' Source #
InvariantT | |
|
VarianceTransformer * k (InvariantT k k) a Source # | |
newtype Invariant1T to f f' Source #
Invariant1T | |
|
Functor m => VarianceTransformer (* -> *) k (Invariant1T k k) m Source # | |
newtype NonvariantT to f f' Source #
If you can't figure out how to map over a particular type parameter, use
this variance and we'll leave it alone. The corresponding infix operator is
(-#-)
.
NonvariantT | |
|
VarianceTransformer k1 k (NonvariantT k1 k k) a Source # | |
newtype PhantomvariantT to f f' Source #
Phantom type parameters can be changed to any other type, no a -> b
function needed, so we only ask for a ()
. Use (-#-)
in the common case
in which you don't want to change the phantom type, and (👻#👻)
in the
rare case in which you do want to change it.
PhantomvariantT | |
|
VarianceTransformer k1 k (PhantomvariantT k1 k1 k k) a Source # | |