https://kotlinlang.org logo
#arrow
Title
# arrow
m

Mervyn McCreight

11/29/2023, 5:49 PM
Hi 🙂 I have a question about the
Raise
DSL: If I’m about to e.g. write a function that does something that can fail for multiple reasons (like calling an API) would it be more arrow idiomatic to write it as an
Effect
:
Copy code
fun something(...): Effect<Error, Whatever>
and leave it up to caller to decide in which kind of context (Either, Option, Result, Whatnot) he wants to call this, or would I rather explicitly write is as an
Either
:
Copy code
suspend fun something(...): Either<Error, Whatever>
The question arises for me, because my first thought when I saw the RaiseDSL and Effect was that defining it as
Raise
or
Effect
and let the caller decide what he wants to have is more flexible and therefor basically the idea of that. But all documentation about “Typed Error Handling” seems to define all public functions in concrete (e.g.
Either
or a suspend fun
Either
) and never exposes something as
Raise
or
Effect
. Whats your opinion about that?
a

AdamW

11/29/2023, 6:27 PM
I would do:
Copy code
fun Raise<Error>.something(…): Whatever { … }
Though if you are already in an extension, this is not possible. Even better with context receivers:
Copy code
context(Raise<Error>)
fun something(…): Whatever { … }
1
y

Youssef Shoaib [MOD]

11/29/2023, 6:28 PM
Raise definitely provides the most flexibility, and the caller can choose to wrap it in an
effect {}
if they so choose
m

Mervyn McCreight

11/29/2023, 8:59 PM
Alright, thanks for your input 🙂 Any other opinions? :)
s

simon.vergauwen

11/30/2023, 7:28 AM
Effect<E, A>
is just an alias for
suspend Raise<E>.() -> A
, so that it becomes more friendly to write
val x: Effect<E, A>
rather than having to write
val x: suspend Raise<E>.() -> A
. Similar to the builder,
effect { }
can correctly infer
E
and
A
and provide
Raise<E>
, but
suspend { }
cannot infer
E
or provide
Raise<E>
. Alternatively,
Either
is the result from executing
suspend Raise<E>.() -> A
. So
Either<E, A>
is the result of executing
Raise<E>.() -> A
. That being said
suspend () -> Either<E, A>
is isomorphic to
suspend Raise<E>.() -> A
that's why you can execute
suspend Raise<E>.() -> A
in
either { }
and
bind
Either<E, A>
inside
suspend Raise<E>.() -> A
. So it's a matter of preference, I think that using
context(Raise<E>)
/
fun Raise<E>.bla(): A
or
Either<E, A>
will be the most popular and
Effect
will rarely be used.
4 Views