Hi all. Question regarding Either and Exception ha...
# arrow
y
Hi all. Question regarding Either and Exception handling. Given we still live in an imperfect world that’s not fully functional, there often comes a time in a program when you need to bridge between the functional parts of your program and imperative parts that still rely on Exceptions being thrown to manage control flow. I find myself leaning on an extension function that looks like this:
Copy code
fun <A,B> Either<A, B>.throwException(f: (A) -> Unit): Unit = when (this) {
    is Either.Left -> f(this.value)
    else -> Unit
}
which I then use like this:
Copy code
val someResult: Either<SomeErrorADT, String> = ...
someResult.throwException { 
  when (it) {
    SomeErrorADT.Error1 -> throw SomeException1("...")
    SomeErrorADT.Error2 -> throw SomeOtherException("...")
  }
}
Is there an existing function or extension function that exists in Arrow that kind of does the same thing that I’m not seeing?
p
tapLeft
(or even
handleError
) should do the job
Copy code
someResult.tapLeft {
    when(it) {
        SomeErrorADT.Error1 -> error("💥")
        SomeErrorADT.Error2 -> error("🐍")
    }
}
y
Yeah, I didn’t like it because the return type is still
Either
when in this case it’s clear we’ll never use the return type. But thanks for the info.
s
imperative parts that still rely on Exceptions being thrown to manage control flow. I find myself leaning on an extension function that looks like this:
That is sometimes indeed a use-case, but it's especially the case when introducing Arrow in existing codebases but it's too niche to promote it in Arrow itself. It's also against the motivation behind Arrow, so we only promote safe patterns such as Phil Davies suggested.
Kotlin prefers to be explicit, and in this case we also think it's better to be explicit that you're throwing. When I run into this I try to hide the "throwing" behind an interface such that it becomes an implementation detail. I.e. when working interopting with some Java libraries that require throwing for control flow.