#arrow
Title
# arrow
e

Erik Dreyer

06/22/2022, 8:37 PM
Is there a way in Arrow to achieve a
``flatMap``
like operation with two methods that produce
``ValidatedNel<E,A>``
where the “right” side of the first method is an input into the second method?
e.g.
Copy code
``````val a: ValidatedNel<E, A> = foo()
val b: ValidatedNel<E, B> = bar(<a's right side>)

// so...
val result: B = a
.map { bar(it) }
.fold(
{ err -> // create a B },
{ result -> // oops, result is a ValidatedNel<E,B>, but I want a B }
)``````
maybe
Copy code
``````val a: Either<Nel<E>, A> = foo().toEither()
val b: Either<Nel<E>, B> = bar(<a's right side>).toEither()

// like this, basically
val result: Either<Nel<E>, B> = a.flatMap { bar(it).toEither() }``````
d

Davis Mohar

06/22/2022, 9:19 PM
I've used the
``withEither{}``
function to achieve this. It will convert a Validated to an either within the block, and then automatically convert it back at the end
👀 1
e

Erik Dreyer

06/22/2022, 9:23 PM
oh, nice
thx!
🙂 1
r

raulraja

06/22/2022, 9:24 PM
if you don’t mind the early short circuit you can also express the dependency sequentially inside
``either``
the tricky part here is that if
``bar``
depends on the result of
``foo``
the
``Nel``
is not needed since you have no way to invoke
``bar``
without the result of
``foo``
You could simplify the types to just
``Validated<String, Int>``
without the Nel.
``Nel``
is only useful when you have independent operations and you would like to perform error accumulation.
which them would become:
e

Erik Dreyer

06/22/2022, 9:29 PM
Thanks Raul. That’s really clean. In my case, the example is a simplification. In the actual project, the results of
``foo()``
and
``bar()``
may have multiple errors, so I’ll have to keep the
``Nel``
. Love the use of comprehensions!
r

raulraja

06/22/2022, 9:29 PM
makes sense, also if you are in the JVM or in the Future with context receivers you can just do:
e

Erik Dreyer

06/22/2022, 9:32 PM
The
``either {}``
dsl is deprecated now in favor of effects?
r

raulraja

06/22/2022, 9:33 PM
it’s not, it’s complementary, but if you have access to context receivers you can further simplify your function return types to avoid wrapping
Consider in this style the happy path has no penalty and the unhappy path when it hits it it handles it throwing a controlled exceptions that plays well with coroutines, inlining etc. It can highly simplify the way you encode programs that have errors
It’s like exceptions but safe because you have to carry the kind of error you may throw in the context type
therefore you don’t need to wrap and use map, flatMap style control flow which usually incurs in additional allocations for each one of the composition steps
👍 1
e

Erik Dreyer

06/22/2022, 9:35 PM
Yes for sure. This is a bit new to me. I love how clean it’s expressed, with error handing baked in without being a distraction. I’m going to have to study this a bit to get my head wrapped around it
👍 1
r

raulraja

06/22/2022, 9:36 PM
feel free to ask any questions or bring any issues!
e

Erik Dreyer

06/22/2022, 9:36 PM
Much appreciated!
ok where does
``context``
come from in
Copy code
``context(EffectScope<String>)``
r

raulraja

06/23/2022, 6:54 AM
If you get latest kotlin and enable multiple context receivers from their docs: https://blog.jetbrains.com/kotlin/2022/02/kotlin-1-6-20-m1-released/#prototype-of-context-receivers-for-kotlin-jvm
``-Xcontext-receivers``
``context``