Raise
The Raise DSL allows you to work with logical failures of type R. A logical failure does not necessarily mean that the computation has failed, but that it has stopped or short-circuited.
The Raise DSL allows you to raise logical failure of type R, and you can recover from them.
fun Raise<String>.failure(): Int = raise("failed")
fun Raise<Nothing>.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 to Nothing. Meaning we can track that we recovered from the error in the type.
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(Semigroup.string()) { failure() }
either shouldBe Either.Left("failed")
effect.toEither() shouldBe Either.Left("failed")
ior shouldBe Ior.Left("failed")
}And we can apply the same technique to recover from the failures using the Raise DSL based error handlers available in Arrow.
fun test() {
val either = either { failure() }
.recover { _: String -> recovered() }
either shouldBe Either.Right(1)
}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.