ApplicativeAsk[F, E]
lets you access an E
value in the F[_]
context.
ApplicativeAsk[F, E]
lets you access an E
value in the F[_]
context.
Intuitively, this means that an E
value is required as an input to get "out" of the F[_]
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) }
ApplicativeLocal[F, E]
lets you alter the E
value that is observed by an F[A]
value
using ask
; the modification can only be observed from within that F[A]
value.
ApplicativeLocal[F, E]
lets you alter the E
value that is observed by an F[A]
value
using ask
; the modification can only be observed from within that F[A]
value.
ApplicativeLocal[F, E]
has three external laws:
def askReflectsLocal(f: E => E) = { local(f)(ask) <-> 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) }
FunctorListen[F, L]
is a function F[A] => F[(A, L)]
which exposes some state
that is contained in all F[A]
values, and can be modified using tell
.
FunctorListen[F, L]
is a function F[A] => F[(A, L)]
which exposes some state
that is contained in all F[A]
values, and can be modified using tell
.
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)) } }
FunctorRaise[F, E]
expresses the ability to raise errors of type E
in a functorial F[_]
context.
FunctorRaise[F, E]
expresses the ability to raise errors of type E
in a functorial F[_]
context.
This means that a value of type F[A]
may contain no A
values but instead an E
error value,
and further map
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.
FunctorTell[F, L]
is the ability to "log" values L
inside a context F[_]
, as an effect.
FunctorTell[F, L]
is the ability to "log" values L
inside a context F[_]
, 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)) }
MonadState[F, S]
is the capability to access and modify a state value
from inside the F[_]
context, using set(s: S): F[Unit]
and get: F[S]
.
MonadState[F, S]
is the capability to access and modify a state value
from inside the F[_]
context, using set(s: S): F[Unit]
and get: 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) }