Hi, i’m learning arrow and wanted to check if the ...
# arrow
j
Hi, i’m learning arrow and wanted to check if the following code is the correct way to add a branch in an either block. That if doesn’t look so functional to me..
Copy code
override suspend fun invoke(command: Command): Either<BusinessError, Unit> = 
        either {
            val responseOne = serviceOne.call(command.data.first).bind()
            val responseTwo = serviceTwo.call(command.data.second).bind()
    
            if (responseOne.amount > responseTwo.amount) {
                serviceThree.call()
            }
        }
e
Bind is deprecated.
Copy code
@Deprecated("$deprecatedInFavorOfEagerEffectScope\nThis object introduces dangerous behavior and will be removed in the next version: <https://github.com/arrow-kt/arrow/issues/2547>")
I think you should do something like:
Copy code
override suspend fun invoke(command: Command): Either<BusinessError, Unit> = 
        either {
            val responseOne = serviceOne.call(command.data.first)
            val responseTwo = serviceTwo.call(command.data.second)

            when {
              responseOne is Either.Right && responseTwo is Either.Right ->  if (responseOne.value.amount > responseTwo.value.amount) {
                serviceThree.call()
              },
             // handle remaining cases, where responses one, or two, or both fail
        }
r
bind
is deprecated in the
computation
package but not on the
continuations
package. Semantically though the way the code is written won't leverage that the second call may be performed in parallel
I think that if you want to run those in parallel you can leverage
parZip
and take advantage we can perform effects inside
either
and go async if needed.
j
Thanks for the answers, parzip was what i was looking for. There is something that it is not very clear to me yet. I started learning Arrow to write functional code, however i ended up getting rid of flatmaps and started writting code like before which seems to be more imperative than functional. Is this the correct way to use Arrow? Where is the best place to learn about it?
r
Yes, Arrow takes advantages of kotlin suspension and the continuation system to achieve the same guarantees you get with something like IO, ZIO or other similar functional data types you find in other langs and frameworks but it does not require you to use complex stacks for map, flatMap and in general operators that otherwise you'd need for composition in those types. In arrow
F<A> -> A
it's possible in a non blocking way and we take advantage of
suspend
to implement that. There is more info around this here https://arrow-kt.io/docs/effects/io/ and feel free to ask here any other questions. Essentially continuations can model all monads and with continuations you can achieve
F<A> -> A
which we call
bind
, with bind you can remove the need for flatMap, map and others.
Arrow and Kotlin has no need for monad transformers, monad stacks or other abstractions you frequently find in Haskell or Scala because with continuations we can bind in place most monads in the same scope. All abstractions are based on a suspend function that can
shift
https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core.continuations/-effect/