Hello Arrow community. I maintain <https://github....
# arrow
i
Hello Arrow community. I maintain https://github.com/fraktalio/fmodel and I am adopting (experimenting with) Arrow 2.0.0-SNAPSHOT (with context receivers). I will explain the case in the thread and your toughs/ideas are much appreciated:
🎉 1
Lets say we have this function which is handling some Command/C and storing new State/S:
Copy code
context (StateComputation<C, S, E>, StateRepository<C, S>, Raise<Error>)
suspend fun <C, S, E> C.handleWithEffect(): S =
    catch({
        fetchState().computeNewState(this@handleWithEffect).save()
    }) {
        raise(CommandHandlingFailed(this, it))
    }
Now, lets handle the Flow of Commands by using ☝️function:
OPTION1:
Copy code
context (StateComputation<C, S, E>, StateRepository<C, S>)
fun <C, S, E> Flow<C>.handleWithEffect(): Flow<Effect<Error, S>> =
    map { effect { it.handleWithEffect() } }.catch { emit(effect { raise(CommandPublishingFailed(it)) }) }
OPTION2:
Copy code
context (StateComputation<C, S, E>, StateRepository<C, S>, Raise<Error>)
fun <C, S, E> Flow<C>.handleWithEffect2(): Flow<S> =
    map { it.handleWithEffect() }.catch { raise(CommandPublishingFailed(it) ) }
OPTION2 is more intuitive to me, but OPTION1 seems to be a better contract. What do you think?
s
Hey @Ivan Dugalic, Option 1 is safer since it always wraps the
effect
correctly, int he second option you need to be sure that
collect
is called inside
effect { }
.
i
Thanks @simon.vergauwen! Indeed.
My observation is that people could end-up in OPTION2, especially once you use context receivers to put Raise<Error> in the scope. It is tempting to return
Flow<S>
🙂 rather then returning explicitly
Flow<Effect<Error, S>>
I am also considering returning
Flow<Either<Error, S>>
rather then
Flow<Effect<Error, S>>
. What do you think? Do you see any cons of using Effect?
s
Either
is definitely a good option also. I would say that
Either
is better understood, and it prevents leaking
raise
operator. It's a good type to use in this case.
Effect
has the ability to be "traced", which also might be useful. Tracing POC Exposing both is probably not useful, since it'll result in signature clashes all over the place.