Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
NAryFunctor
- 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) ...
Minimal complete definition
Associated Types
type VarianceStack f :: k -> k -> * Source #
Methods
nmap :: VarianceStack f f f Source #
Instances
(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 ()
.
Minimal complete definition
Instances
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 #
Constructors
CovariantT | |
Fields
|
Instances
VarianceTransformer * k (CovariantT k k) a Source # | |
newtype Covariant1T to f f' Source #
Constructors
Covariant1T | |
Instances
Functor m => VarianceTransformer (* -> *) k (Covariant1T k k) m Source # | |
newtype ContravariantT to f f' Source #
Constructors
ContravariantT | |
Fields
|
Instances
VarianceTransformer * k (ContravariantT k k) a Source # | |
newtype Contravariant1T to f f' Source #
Constructors
Contravariant1T | |
Instances
Functor m => VarianceTransformer (* -> *) k (Contravariant1T k k) m Source # | |
newtype InvariantT to f f' Source #
Constructors
InvariantT | |
Fields
|
Instances
VarianceTransformer * k (InvariantT k k) a Source # | |
newtype Invariant1T to f f' Source #
Constructors
Invariant1T | |
Fields
|
Instances
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
(-#-)
.
Constructors
NonvariantT | |
Fields
|
Instances
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.
Constructors
PhantomvariantT | |
Fields
|
Instances
VarianceTransformer k1 k (PhantomvariantT k1 k1 k k) a Source # | |