ApplicativeLayer[M, Inner]
has the following functionality:
- the capability to lift values from the Applicative
Inner
to the Applicative
M
, preserving the Applicative
structure
- lifts Applicative
isomorphisms in Inner
((Inner ~> Inner, Inner ~> Inner)
)
into Applicative
homomorphisms in M
(M ~> M
).
ApplicativeLayerFunctor
is the capability to lift Applicative
homomorphisms
in Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
ApplicativeLayerFunctor
is the capability to lift Applicative
homomorphisms
in Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
ApplicativeLayerFunctor[M, Inner]
has no additional laws.
FunctorLayer[M, Inner]
has the following functionality:
- lifts values from the Functor
Inner
to the Functor
M
.
FunctorLayer[M, Inner]
has the following functionality:
- lifts values from the Functor
Inner
to the Functor
M
.
- lifts Functor
isomorphisms in Inner
((Inner ~> Inner, Inner ~> Inner)
)
into Functor
homomorphisms in M
(M ~> M
).
This allows you to "map" a natural transformation over the Inner
inside M
,
but only if you can provide an inverse of that natural transformation.
FunctorLayer[M, Inner]
has two external laws:
def mapForwardRespectsLayer[A](in: Inner[A])(forward: Inner ~> Inner, backward: Inner ~> Inner) = { layer(forward(in)) <-> layerImapK(layer(in))(forward, backward) } def layerImapRespectsId[A](in: M[A]) = { in <-> layerImapK(in)(FunctionK.id, FunctionK.id) }
FunctorLayer
has one free law, i.e. a law guaranteed by parametricity:
def layerRespectsMap[A, B](in: Inner[A])(f: A => B) = { layer(in.map(f)) <-> layer(in).map(f) } // this is free because all `FunctionK`'s (including `layer`, despite not being an instance of the class) // are natural transformations (i.e., they follow this law exactly)
FunctorLayerFunctor
is the capability to lift Functor
homomorphisms in
Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
FunctorLayerFunctor
is the capability to lift Functor
homomorphisms in
Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
FunctorLayerFunctor[M, Inner]
has two external laws:
def layerMapRespectsLayerImapK[A](ma: M[A])(forward: Inner ~> Inner, backward: Inner ~> Inner) = { layerImapK(ma)(forward, backward) <-> layerMapK(ma)(forward) } def layerMapRespectsLayer[A](in: Inner[A])(forward: Inner ~> Inner) = { layer(forward(in)) <-> layerMapK(layer(in))(forward) }
FunctorLayerFunctor[M, Inner]
has one free law, that is,
one law guaranteed by other laws and parametricity:
def layerMapRespectsId[A](in: M[A]) = { in <-> layerImapK(in)(FunctionK.id, FunctionK.id) } Justification: layerImapK(in)(FunctionK.id, FunctionK.id) <-> in [by layerMapRespectsLayerImapK[A]] layerMapK(in)(FunctionK.id) <-> layerImapK(FunctionK.id, FunctionK.id) [by layerImapRespectsId[A]]
MonadLayer[M, Inner]
has the following functionality:
- lifts values from the Monad
Inner
to the Monad
M
.
MonadLayer[M, Inner]
has the following functionality:
- lifts values from the Monad
Inner
to the Monad
M
.
- lifts Monad
isomorphisms in Inner
((Inner ~> Inner, Inner ~> Inner)
)
into Monad
homomorphisms in M
(M ~> M
).
This allows you to "map" a natural transformation over the Inner
inside M
,
but only if you can provide an inverse of that natural transformation.
MonadLayer
has one external law:
def layerRespectsFlatMap[A, B](m: Inner[A])(f: A => Inner[B]) = { layer(m).flatMap(f andThen layer) <-> layer(m.flatMap(f)) }
MonadLayerControl is possible to use to access lower monad layers in invariant position, as in so-called "control operations".
MonadLayerControl is possible to use to access lower monad layers in invariant position, as in so-called "control operations".
Three external laws:
def layerMapRespectsLayerControl[A](m: M[A], f: Inner ~> Inner) = { layerMapK(m)(f) <-> layerControl(run => f(run(m)).flatMap(restore) } def distributionLaw[A](nt: State ~> State, st: State[A]) = { restore(nt(st)) <-> layerControl[State[A]](_ (restore(st)).map(nt(_))).flatMap(restore) } def layerControlIdentity[A](ma: M[A]) = { ma <-> layerControl[Inner[State[A]]] { cps => cps(ma).pure[Inner] }.flatMap(layer).flatMap(restore) }
MonadLayerFunctor
is the capability to lift Monad
homomorphisms
in Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
MonadLayerFunctor
is the capability to lift Monad
homomorphisms
in Inner
(Inner ~> Inner
) into homomorphisms in M
(Inner ~> Inner
).
MonadLayerFunctor[M, Inner]
has no additional laws.
ApplicativeLayer[M, Inner]
has the following functionality: - the capability to lift values from theApplicative
Inner
to theApplicative
M
, preserving theApplicative
structure - liftsApplicative
isomorphisms inInner
((Inner ~> Inner, Inner ~> Inner)
) intoApplicative
homomorphisms inM
(M ~> M
). This allows you to "map" a natural transformation over theInner
insideM
, but only if you can provide an inverse of that natural transformation.ApplicativeLayer[M, Inner]
has two external laws: