package mtl
- Alphabetic
- By Inheritance
- mtl
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Type Members
-
trait
ApplicativeAsk[F[_], E] extends Serializable
ApplicativeAsk[F, E]
lets you access anE
value in theF[_]
context.ApplicativeAsk[F, E]
lets you access anE
value in theF[_]
context.Intuitively, this means that an
E
value is required as an input to get "out" of theF[_]
context.ApplicativeAsk[F, E]
has one external law:def askAddsNoEffects[A](fa: F[A]) = { (ask *> fa) <-> fa }
ApplicativeAsk[F, E]
has one internal law:def readerIsAskAndMap[A](f: E => A) = { ask.map(f) <-> reader(f) }
-
trait
ApplicativeLayer[M[_], Inner[_]] extends FunctorLayer[M, Inner] with Serializable
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
).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:def layerRespectsPure[A](a: A) = { layer(a.pure[Inner]) <-> a.pure[M] } def layerRespectsAp[A, B](m: Inner[A])(f: Inner[A => B]) = { layer(m).ap(layer(f)) <-> layer(m.ap(f)) }
-
trait
ApplicativeLayerFunctor[M[_], Inner[_]] extends ApplicativeLayer[M, Inner] with FunctorLayerFunctor[M, Inner] with Serializable
ApplicativeLayerFunctor
is the capability to liftApplicative
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(Inner ~> Inner
).ApplicativeLayerFunctor
is the capability to liftApplicative
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(Inner ~> Inner
).ApplicativeLayerFunctor[M, Inner]
has no additional laws. -
trait
ApplicativeLocal[F[_], E] extends Serializable
ApplicativeLocal[F, E]
lets you alter theE
value that is observed by anF[A]
value usingask
; the modification can only be observed from within thatF[A]
value.ApplicativeLocal[F, E]
lets you alter theE
value that is observed by anF[A]
value usingask
; the modification can only be observed from within thatF[A]
value.ApplicativeLocal[F, E]
has three external laws:def askReflectsLocal(f: E => E) = { local(ask)(f) <-> ask map f } def localPureIsPure[A](a: A, f: E => E) = { local(f)(pure(a)) <-> pure(a) } def localDistributesOverAp[A, B](fa: F[A], ff: F[A => B], f: E => E) = { local(f)(ff ap fa) <-> local(f)(ff) ap local(f)(fa) }
ApplicativeLocal
has one internal law:def scopeIsLocalConst(fa: F[A], e: E) = { scope(e)(fa) <-> local(_ => e)(fa) }
- trait DefaultApplicativeAsk[F[_], E] extends ApplicativeAsk[F, E]
- trait DefaultApplicativeLocal[F[_], E] extends ApplicativeLocal[F, E]
- trait DefaultFunctorEmpty[F[_]] extends FunctorEmpty[F]
- trait DefaultFunctorTell[F[_], L] extends FunctorTell[F, L]
- trait DefaultMonadState[F[_], S] extends MonadState[F, S]
- trait DefaultTraverseEmpty[F[_]] extends TraverseEmpty[F]
-
trait
FunctorEmpty[F[_]] extends Serializable
FunctorEmpty[F]
allows you tomap
and filter out elements simultaneously.FunctorEmpty[F]
allows you tomap
and filter out elements simultaneously.FunctorEmpty
has two external laws:def mapFilterComposition[A, B, C](fa: F[A], f: A => Option[B], g: B => Option[C]) = { val lhs: F[C] = fa.mapFilter(f).mapFilter(g) val rhs: F[C] = fa.mapFilter(a => f(a).flatMap(g)) lhs <-> rhs } def mapFilterMapConsistency[A, B](fa: F[A], f: A => B) = { fa.mapFilter(f andThen (_.some)) <-> fa.map(f) }
FunctorEmpty
has three internal laws:def collectConsistentWithMapFilter[A, B](fa: F[A], f: PartialFunction[A, B]) = { collect(fa)(f) <-> mapFilter(fa)(f.lift) } def flattenOptionConsistentWithMapFilter[A](fa: F[Option[A]]) = { flattenOption(fa) <-> mapFilter(fa)(identity) } def filterConsistentWithMapFilter[A](fa: F[A], f: A => Boolean) = { filter(fa)(f) <-> mapFilter(fa)(a => if (f(a)) Some(a) else None) }
-
trait
FunctorLayer[M[_], Inner[_]] extends Serializable
FunctorLayer[M, Inner]
has the following functionality: - lifts values from theFunctor
Inner
to theFunctor
M
.FunctorLayer[M, Inner]
has the following functionality: - lifts values from theFunctor
Inner
to theFunctor
M
. - liftsFunctor
isomorphisms inInner
((Inner ~> Inner, Inner ~> Inner)
) intoFunctor
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.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)
-
trait
FunctorLayerFunctor[M[_], Inner[_]] extends FunctorLayer[M, Inner] with Serializable
FunctorLayerFunctor
is the capability to liftFunctor
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(Inner ~> Inner
).FunctorLayerFunctor
is the capability to liftFunctor
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(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]]
-
trait
FunctorListen[F[_], L] extends Serializable
FunctorListen[F, L]
is a functionF[A] => F[(A, L)]
which exposes some state that is contained in allF[A]
values, and can be modified usingtell
.FunctorListen[F, L]
is a functionF[A] => F[(A, L)]
which exposes some state that is contained in allF[A]
values, and can be modified usingtell
.FunctorListen
has two external laws:def listenRespectsTell(l: L) = { listen(tell(l)) <-> tell(l).as(((), l)) } def listenAddsNoEffects(fa: F[A]) = { listen(fa).map(_._1) <-> fa }
FunctorListen
has one internal law:def listensIsListenThenMap(fa: F[A], f: L => B) = { listens(fa)(f) <-> listen(fa).map { case (a, l) => (a, f(l)) } }
-
trait
FunctorRaise[F[_], E] extends Serializable
FunctorRaise[F, E]
expresses the ability to raise errors of typeE
in a functorialF[_]
context.FunctorRaise[F, E]
expresses the ability to raise errors of typeE
in a functorialF[_]
context. This means that a value of typeF[A]
may contain noA
values but instead anE
error value, and furthermap
calls will not have any values to execute the passed function on.FunctorRaise
has no external laws.FunctorRaise
has two internal laws:def catchNonFatalDefault[A](a: => A)(f: Throwable => E)(implicit A: Applicative[F]) = { catchNonFatal(a)(f) <-> try { A.pure(a) } catch { case NonFatal(ex) => raise(f(ex)) } } def ensureDefault[A](fa: F[A])(error: => E)(predicate: A => Boolean)(implicit A: Monad[F]) = { ensure(fa)(error)(predicate) <-> for { a <- fa _ <- if (predicate(a)) pure(()) else raise(error) } yield a }
FunctorRaise
has one free law, i.e. a law guaranteed by parametricity:def failThenFlatMapFails[A, B](ex: E, f: A => F[B]) = { fail(ex).flatMap(f) <-> fail(ex) } guaranteed by: fail[X](ex) <-> fail[F[Y]](ex) // parametricity fail[X](ex).map(f) <-> fail[F[Y]](ex) // map must have no effect, because there's no X value fail[X](ex).map(f).join <-> fail[F[Y]].join // add join to both sides fail(ex).flatMap(f) <-> fail(ex) // join is equal, because there's no inner value to flatten effects from // QED.
-
trait
FunctorTell[F[_], L] extends Serializable
FunctorTell[F, L]
is the ability to "log" valuesL
inside a contextF[_]
, as an effect.FunctorTell[F, L]
is the ability to "log" valuesL
inside a contextF[_]
, as an effect.FunctorTell
has no external laws.FunctorTell
has one internal law:def writerIsTellAndMap(a: A, l: L) = { (tell(l) as a) <-> writer(a, l) } def tupleIsWriterFlipped(a: A, l: L) = { writer(a, l) <-> tuple((l, a)) }
-
trait
MonadLayer[M[_], Inner[_]] extends ApplicativeLayer[M, Inner]
MonadLayer[M, Inner]
has the following functionality: - lifts values from theMonad
Inner
to theMonad
M
.MonadLayer[M, Inner]
has the following functionality: - lifts values from theMonad
Inner
to theMonad
M
. - liftsMonad
isomorphisms inInner
((Inner ~> Inner, Inner ~> Inner)
) intoMonad
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.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)) }
-
trait
MonadLayerControl[M[_], Inner[_]] extends MonadLayerFunctor[M, Inner]
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) }
-
trait
MonadLayerFunctor[M[_], Inner[_]] extends MonadLayer[M, Inner] with ApplicativeLayerFunctor[M, Inner]
MonadLayerFunctor
is the capability to liftMonad
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(Inner ~> Inner
).MonadLayerFunctor
is the capability to liftMonad
homomorphisms inInner
(Inner ~> Inner
) into homomorphisms inM
(Inner ~> Inner
).MonadLayerFunctor[M, Inner]
has no additional laws. -
trait
MonadState[F[_], S] extends Serializable
MonadState[F, S]
is the capability to access and modify a state value from inside theF[_]
context, usingset(s: S): F[Unit]
andget: F[S]
.MonadState[F, S]
is the capability to access and modify a state value from inside theF[_]
context, usingset(s: S): F[Unit]
andget: F[S]
.MonadState has four external laws:
def getThenSetDoesNothing = { get >>= set <-> pure(()) } def setThenGetReturnsSetted(s: S) = { set(s) *> get <-> set(s) *> pure(s) } def setThenSetSetsLast(s1: S, s2: S) = { set(s1) *> set(s2) <-> set(s2) } def getThenGetGetsOnce = { get *> get <-> get }
MonadState
has two internal law:def modifyIsGetThenSet(f: S => S) = { modify(f) <-> (inspect(f) flatMap set) } def inspectLaw[A](f: S => A) = { inspect(f) <-> (get map f) }
-
trait
TraverseEmpty[F[_]] extends Serializable
TraverseEmpty
, also known asWitherable
, represents list-like structures that can essentially have atraverse
and afilter
applied as a single combined operation (traverseFilter
).TraverseEmpty
, also known asWitherable
, represents list-like structures that can essentially have atraverse
and afilter
applied as a single combined operation (traverseFilter
).TraverseEmpty
has two external laws:def traverseFilterIdentity[G[_]: Applicative, A](fa: F[A]) = { fa.traverseFilter(_.some.pure[G]) <-> fa.pure[G] } def traverseFilterComposition[A, B, C, M[_], N[_]](fa: F[A], f: A => M[Option[B]], g: B => N[Option[C]] )(implicit M: Applicative[M], N: Applicative[N] ) = { val lhs = Nested[M, N, F[C]](fa.traverseFilter(f).map(_.traverseFilter(g))) val rhs: Nested[M, N, F[C]] = fa.traverseFilter[NestedC[M, N]#l, C](a => Nested[M, N, Option[C]](f(a).map(_.traverseFilter(g))) ) lhs <-> rhs }
TraverseEmpty
has one internal law:def filterAConsistentWithTraverseFilter[G[_]: Applicative, A](fa: F[A], f: A => G[Boolean]) = { filterA(fa)(f) <-> fa.traverseFilter(a => G.map(f(a))(if (_) Some(a) else None)) }
Based on Haskell's Data.Witherable
Value Members
- object ApplicativeAsk extends Serializable
- object ApplicativeLayer extends Serializable
- object ApplicativeLayerFunctor extends Serializable
- object ApplicativeLocal extends Serializable
- object FunctorEmpty extends Serializable
- object FunctorLayer extends Serializable
- object FunctorLayerFunctor extends Serializable
- object FunctorListen extends Serializable
- object FunctorRaise extends Serializable
- object FunctorTell extends Serializable
- object MonadLayer extends Serializable
- object MonadLayerControl extends Serializable
- object MonadLayerFunctor extends Serializable
- object MonadState extends Serializable
- object TraverseEmpty extends Serializable