Ulrich Schuster
02/15/2024, 10:36 AMEither.catch{..}
and the raise
DSL? I'm having the following problem:
either {
zipOrAccumulate(
{ ensureNotNull(<some function>) { MyErrorType1 },
{ ensureNotNull(<some other function>) { MyErrorType2 },
{ Either.catch { MyEnum.valueOf(someString) }.mapLeft { MyErrorType3 }
) { a, b, c -> MyType(a, b, c)
}
The Either.catch
block does not type check, because the result is not compatible with the raise
DSL. What is the idiomatic way to do it?dave08
02/15/2024, 10:41 AMEither.
)?Ulrich Schuster
02/15/2024, 10:46 AMUlrich Schuster
02/15/2024, 10:48 AMeither {
zipOrAccumulate(
{ ensureNotNull(<some function>) { MyErrorType1 },
{ ensureNotNull(<some other function>) { MyErrorType2 },
{ catch( { MyEnum.valueOf(someString) } ) { raise(MyErrorType3) } }
) { a, b, c -> MyType(a, b, c)
}
simon.vergauwen
02/15/2024, 3:46 PMRaise<E>
then you can call Either.bind
on Either<E, A>
.
So I am assuming in this case that MyErrorType1
, MyErrorType2
and MyErrorType3
have a common parent. I am going to define one MyError
so:
sealed interface MyError // (or sealed class)
object MyErrorType1 : MyError
object MyErrorType2 : MyError
object MyErrorType3 : MyError
And then we need to apply bind
within your previous snippet so:
either/*<NonEmptyList<MyError>, MyType>*/ { /* Raise<E>.() -> */
zipOrAccumulate(
{ ensureNotNull(<some function>) { MyErrorType1 },
{ ensureNotNull(<some other function>) { MyErrorType2 },
{ Either.catch { MyEnum.valueOf(someString) }.mapLeft { MyErrorType3 }.bind() }
) { a, b, c -> MyType(a, b, c) }
}
simon.vergauwen
02/15/2024, 3:48 PMRaise
, and Either
are always interchangeable.
To go from Either<E, A>
to A
in Raise
you need to make sure that the generic parameter of Raise
matches the error type of Either
in this case E
. (common parent).
To go from Raise<E>
to A
you use the either { }
builder, or DSL. Which you're also already using here.
So if you work with Either
using either { }
, then you're in fact already using Raise
all the time ☺️simon.vergauwen
02/15/2024, 3:51 PMEither
as a "wrapper type", and Raise<E>
relies on DSLs and never requires wrapping values.
You can also see this all over the Kotlin ecosystem:
• Option
is a wrapper, ?
is unwrapped.
• Future
(wrapper), and as suspend
(unwrapped)
However, there are many people that prefer using Either
over Raise
(which kind-of implies context receivers to all benefits from it). At least, that is our prediction/expectation.Ulrich Schuster
02/15/2024, 3:52 PMsimon.vergauwen
02/15/2024, 4:18 PM