https://kotlinlang.org logo
#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
To enable context receivers in your project, use the
-Xcontext-receivers
compiler option.
Then you get access to
context
🙏 1
3 Views