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.
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:FunctorRaise
has one free law, i.e. a law guaranteed by parametricity: