Raise
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
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.
Invoke an EagerEffect inside this
Raise context. Any logical failure is raised in this
Raise context, and thus short-circuits the computation.
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.
Extracts all the values in the Iterable, raising every Either.Left as a logical failure. In other words, executed bind over every value in this Iterable.
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.
Invoke an EagerEffect inside this
Raise context. Any logical failure is raised in this
Raise context, and thus short-circuits the computation.
Accumulate the errors obtained by executing the transform over every element of NonEmptyList.
Accumulate the errors obtained by executing the transform over every element of NonEmptySet.
Transform every element of iterable using the given transform, or accumulate all the occurred errors using combine.
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.
Accumulate the errors from running action1, action2, action3, action4, and action5 using the given combine.
Accumulate the errors from running action1, action2, action3, action4, action5, and action6 using the given combine.
Accumulate the errors from running action1, action2, action3, action4, action5, action6, and action7.
Accumulate the errors from running action1, action2, action3, action4, action5, action6, and action7 using the given combine.
Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, and action8.
Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, and action8 using the given combine.
Accumulate the errors from running action1, action2, action3, action4, action5, action6, action7, action8, and action9.