Raise

interface Raise<in Error>

The Raise DSL allows you to work with logical failures of type Error. A logical failure does not necessarily mean that the computation has failed, but that it has stopped or short-circuited. The Arrow website has a guide introducing Raise and how to use it effectively.

The Raise DSL allows you to raise logical failure of type Error, and you can recover from them.

fun Raise<String>.failure(): Int = raise("failed")

fun recovered(): Int =
recover({ failure() }) { _: String -> 1 }

Above we defined a function failure that raises a logical failure of type String with value "failed". And in the function recovered we recover from the failure by providing a fallback value, and resolving the error type String.

You can also use the recover function inside the Raise DSL to transform the error type to a different type such as List<Char>. And you can do the same for other data types such as Effect, Either, etc. using getOrElse as an alternative to recover.

fun Raise<String>.failure(): Int = raise("failed")

fun Raise<List<Char>>.recovered(): Int =
recover({ failure() }) { msg: String -> raise(msg.toList()) }

suspend fun Raise<List<Char>>.recovered2(): Int =
effect { failure() } getOrElse { msg: String -> raise(msg.toList()) }

fun Raise<List<Char>>.recovered3(): Int =
"failed".left() getOrElse { msg: String -> raise(msg.toList()) }

fun test(): Unit {
recover({ "failed".left().bind() }) { 1 } shouldBe "failed".left().getOrElse { 1 }
}

Since we defined programs in terms of Raise they seamlessly work with any of the builders available in Arrow, or any you might build for your custom types.

suspend fun test() {
val either: Either<String, Int> =
either { failure() }

val effect: Effect<String, Int> =
effect { failure() }

val ior: Ior<String, Int> =
ior(String::plus) { failure() }

either shouldBe Either.Left("failed")
effect.toEither() shouldBe Either.Left("failed")
ior shouldBe Ior.Left("failed")
}

Arrow also exposes Raise based error handlers for the most common data types, which allows to recover from logical failures whilst transforming the error type.

fun Raise<String>.failure(): Int = raise("failed")

fun test() {
val failure: Either<String, Int> = either { failure() }

failure.recover { _: String -> 1.right().bind() } shouldBe Either.Right(1)

failure.recover { msg: String -> raise(msg.toList()) } shouldBe Either.Left(listOf('f', 'a', 'i', 'l', 'e', 'd'))

recover({ failure.bind() }) { 1 } shouldBe failure.getOrElse { 1 }
}

Inheritors

Functions

Link copied to clipboard
inline fun <Error, A> Raise<NonEmptyList<Error>>.accumulate(block: RaiseAccumulate<Error>.() -> A): A
Link copied to clipboard
open fun <A> Either<Error, A>.bind(): A

Extract the Either.Right value of an Either. Any encountered Either.Left will be raised as a logical failure in this Raise context. You can wrap the bind call in recover if you want to attempt to recover from any logical failure.

open fun <A> EagerEffect<Error, A>.bind(): A

Invoke an EagerEffect inside this Raise context. Any logical failure is raised in this Raise context, and thus short-circuits the computation.

open suspend fun <A> Effect<Error, A>.bind(): A

Invoke an Effect inside this Raise context. Any logical failure raised are raised in this Raise context, and thus short-circuits the computation.

Link copied to clipboard

Extracts all the values in the NonEmptyList, raising every Either.Left as a logical failure. In other words, executed bind over every value in this NonEmptyList.

Extracts all the values in the NonEmptySet, raising every Either.Left as a logical failure. In other words, executed bind over every value in this NonEmptySet.

open fun <A> Iterable<Either<Error, A>>.bindAll(): List<A>

open fun <K, A> Map<K, Either<Error, A>>.bindAll(): Map<K, A>

Extracts all the values in the Map, raising every Either.Left as a logical failure. In other words, executed bind over every value in this Map.

Link copied to clipboard
inline fun <Error> Raise<Error>.ensure(condition: Boolean, raise: () -> Error)

Ensures that the condition is met; otherwise, Raise.raises a logical failure of type Error.

Link copied to clipboard
inline fun <Error, B : Any> Raise<Error>.ensureNotNull(value: B?, raise: () -> Error): B

Ensures that the value is not null; otherwise, Raise.raises a logical failure of type Error.

Link copied to clipboard
inline fun <Error, A> Raise<Error>.forEachAccumulating(iterable: Iterable<A>, combine: (Error, Error) -> Error, block: RaiseAccumulate<Error>.(A) -> Unit)
inline fun <Error, A> Raise<Error>.forEachAccumulating(iterator: Iterator<A>, combine: (Error, Error) -> Error, block: RaiseAccumulate<Error>.(A) -> Unit)
inline fun <Error, A> Raise<Error>.forEachAccumulating(sequence: Sequence<A>, combine: (Error, Error) -> Error, block: RaiseAccumulate<Error>.(A) -> Unit)
Link copied to clipboard
open operator fun <A> EagerEffect<Error, A>.invoke(): A

Invoke an EagerEffect inside this Raise context. Any logical failure is raised in this Raise context, and thus short-circuits the computation.

open suspend operator fun <A> Effect<Error, A>.invoke(): A

Invoke an Effect inside this Raise context. Any logical failure raised are raised in this Raise context, and thus short-circuits the computation.

Link copied to clipboard
inline fun <Error, A, B> Raise<NonEmptyList<Error>>.mapOrAccumulate(nonEmptyList: NonEmptyList<A>, transform: RaiseAccumulate<Error>.(A) -> B): NonEmptyList<B>

Accumulate the errors obtained by executing the transform over every element of NonEmptyList.

inline fun <Error, A, B> Raise<NonEmptyList<Error>>.mapOrAccumulate(nonEmptySet: NonEmptySet<A>, transform: RaiseAccumulate<Error>.(A) -> B): NonEmptySet<B>

Accumulate the errors obtained by executing the transform over every element of NonEmptySet.

inline fun <Error, A, B> Raise<NonEmptyList<Error>>.mapOrAccumulate(iterable: Iterable<A>, transform: RaiseAccumulate<Error>.(A) -> B): List<B>

Accumulate the errors obtained by executing the transform over every element of iterable.

inline fun <K, Error, A, B> Raise<NonEmptyList<Error>>.mapOrAccumulate(map: Map<K, A>, transform: RaiseAccumulate<Error>.(Map.Entry<K, A>) -> B): Map<K, B>
inline fun <K, Error, A, B> Raise<Error>.mapOrAccumulate(map: Map<K, A>, combine: (Error, Error) -> Error, transform: RaiseAccumulate<Error>.(Map.Entry<K, A>) -> B): Map<K, B>

inline fun <Error, A, B> Raise<NonEmptyList<Error>>.mapOrAccumulate(sequence: Sequence<A>, transform: RaiseAccumulate<Error>.(A) -> B): List<B>

Accumulate the errors obtained by executing the transform over every element of sequence.

inline fun <Error, A, B> Raise<Error>.mapOrAccumulate(iterable: Iterable<A>, combine: (Error, Error) -> Error, transform: RaiseAccumulate<Error>.(A) -> B): List<B>

Transform every element of iterable using the given transform, or accumulate all the occurred errors using combine.

inline fun <Error, A, B> Raise<Error>.mapOrAccumulate(sequence: Sequence<A>, combine: (Error, Error) -> Error, transform: RaiseAccumulate<Error>.(A) -> B): List<B>

Transform every element of sequence using the given transform, or accumulate all the occurred errors using combine.

Link copied to clipboard
inline fun <K, Error, A, B> Raise<NonEmptyList<Error>>.mapValuesOrAccumulate(map: Map<K, A>, transform: RaiseAccumulate<Error>.(Map.Entry<K, A>) -> B): Map<K, B>
inline fun <K, Error, A, B> Raise<Error>.mapValuesOrAccumulate(map: Map<K, A>, combine: (Error, Error) -> Error, transform: RaiseAccumulate<Error>.(Map.Entry<K, A>) -> B): Map<K, B>
Link copied to clipboard
abstract fun raise(r: Error): Nothing

Raises a logical failure of type Error. This function behaves like a return statement, immediately short-circuiting and terminating the computation.

Link copied to clipboard
inline fun <Error, A> Raise<Error>.traced(block: Raise<Error>.() -> A, trace: (trace: Trace, error: Error) -> Unit): A

Inspect a Trace value of Error.

Link copied to clipboard
inline fun <Error, OtherError, A> Raise<Error>.withError(transform: (OtherError) -> Error, block: Raise<OtherError>.() -> A): A

Execute the Raise context function resulting in A or any logical error of type OtherError, and transform any raised OtherError into Error, which is raised to the outer Raise.

Link copied to clipboard
inline fun <Error, A, B, C> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, block: (A, B) -> C): C

Accumulate the errors from running both action1 and action2.

inline fun <Error, A, B, C> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, block: (A, B) -> C): C

Accumulate the errors from running both action1 and action2 using the given combine function.

inline fun <Error, A, B, C, D> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, block: (A, B, C) -> D): D

Accumulate the errors from running action1, action2, and action3.

inline fun <Error, A, B, C, D> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, block: (A, B, C) -> D): D

Accumulate the errors from running action1, action2, and action3 using the given combine.

inline fun <Error, A, B, C, D, E> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, block: (A, B, C, D) -> E): E

Accumulate the errors from running action1, action2, action3, and action4.

inline fun <Error, A, B, C, D, E> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, block: (A, B, C, D) -> E): E

Accumulate the errors from running action1, action2, action3, and action4 using the given combine.

inline fun <Error, A, B, C, D, E, F> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, block: (A, B, C, D, E) -> F): F

Accumulate the errors from running action1, action2, action3, action4, and action5.

inline fun <Error, A, B, C, D, E, F> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, block: (A, B, C, D, E) -> F): F

Accumulate the errors from running action1, action2, action3, action4, and action5 using the given combine.

inline fun <Error, A, B, C, D, E, F, G> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, block: (A, B, C, D, E, F) -> G): G

Accumulate the errors from running action1, action2, action3, action4, action5, and action6.

inline fun <Error, A, B, C, D, E, F, G> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, block: (A, B, C, D, E, F) -> G): G

Accumulate the errors from running action1, action2, action3, action4, action5, and action6 using the given combine.

inline fun <Error, A, B, C, D, E, F, G, H> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, block: (A, B, C, D, E, F, G) -> H): H

Accumulate the errors from running action1, action2, action3, action4, action5, action6, and action7.

inline fun <Error, A, B, C, D, E, F, G, H> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, block: (A, B, C, D, E, F, G) -> H): H

Accumulate the errors from running action1, action2, action3, action4, action5, action6, and action7 using the given combine.

inline fun <Error, A, B, C, D, E, F, G, H, I> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, action8: RaiseAccumulate<Error>.() -> H, block: (A, B, C, D, E, F, G, H) -> I): I

Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, and action8.

inline fun <Error, A, B, C, D, E, F, G, H, I> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, action8: RaiseAccumulate<Error>.() -> H, block: (A, B, C, D, E, F, G, H) -> I): I

Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, and action8 using the given combine.

inline fun <Error, A, B, C, D, E, F, G, H, I, J> Raise<NonEmptyList<Error>>.zipOrAccumulate(action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, action8: RaiseAccumulate<Error>.() -> H, action9: RaiseAccumulate<Error>.() -> I, block: (A, B, C, D, E, F, G, H, I) -> J): J

Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, action8, and action9.

inline fun <Error, A, B, C, D, E, F, G, H, I, J> Raise<Error>.zipOrAccumulate(combine: (Error, Error) -> Error, action1: RaiseAccumulate<Error>.() -> A, action2: RaiseAccumulate<Error>.() -> B, action3: RaiseAccumulate<Error>.() -> C, action4: RaiseAccumulate<Error>.() -> D, action5: RaiseAccumulate<Error>.() -> E, action6: RaiseAccumulate<Error>.() -> F, action7: RaiseAccumulate<Error>.() -> G, action8: RaiseAccumulate<Error>.() -> H, action9: RaiseAccumulate<Error>.() -> I, block: (A, B, C, D, E, F, G, H, I) -> J): J

Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, action8, and action9 using the given combine.