MonadError

intermediate

MonadError is the typeclass used to explicitly represent errors during sequential execution. It is parametrized to an error type E, which means the datatype has at least a “success” and a “failure” version. These errors can come in the form of Throwable, Exception, or any other type hierarchy of the user’s choice.

MonadError extends from ApplicativeError, which is already used to represent errors in independent computations. This way all the methods ApplicativeError provides to handle recovery from errors are also available in MonadError.

Main Combinators

MonadError inherits all the combinators available in ApplicativeError and Monad. It also adds one of its own.

raiseError

Inherited from ApplicativeError. A constructor function. It lifts an exception into the computational context of a type constructor.

import arrow.*
import arrow.core.*
import arrow.instances.*
import arrow.instances.either.applicativeError.*

val eitherResult: Either<Throwable, Int> = 
  RuntimeException("BOOM!").raiseError()

eitherResult
// Left(a=java.lang.RuntimeException: BOOM!)
import arrow.data.*
import arrow.instances.`try`.applicativeError.*

val tryResult: Try<Int> = 
  RuntimeException("BOOM!").raiseError()

tryResult
// Failure(exception=java.lang.RuntimeException: BOOM!)
import arrow.effects.*
import arrow.effects.instances.io.applicativeError.*

val ioResult: IO<Int> = 
  RuntimeException("BOOM!").raiseError()
  
ioResult.attempt().unsafeRunSync()
// Left(a=java.lang.RuntimeException: BOOM!)

Kind<F, A>.ensure

Tests a predicate against the object, and if it fails it executes a function to create an error.

import arrow.instances.either.monadError.*

Either.Right(1).ensure({ RuntimeException("Failed predicate") }, { it > 0 }) 
// Right(b=1)
Either.Right(1).ensure({ RuntimeException("Failed predicate") }, { it < 0 }) 
// Left(a=java.lang.RuntimeException: Failed predicate)

Comprehensions

bindingCatch

It starts a Monad Comprehension that wraps any exception thrown in the block inside raiseError().

Laws

Arrow provides MonadErrorLaws in the form of test cases for internal verification of lawful instances and third party apps creating their own MonadError instances.

Data types

The following datatypes in Arrow provide instances that adhere to the MonadError typeclass.