Hi! Probably a basic question, about `either{}` DS...
# arrow
g
Hi! Probably a basic question, about
either{}
DSL. The return type of this is
Either<E,A>
, so I understand one way the composition trips to
left
is -- one of the functions inside returns an either in
left
I am unable to figure out how to explicitly return an either in
left
from within the block. For example:
Copy code
val result: Either<String, String> = either { // This casts the side-effect function into a suspend function.
            val id = !getSomethingFromDb(true)
            val data = !getSomethingElseFromNetwork(id)
           val either = if (data.isEmpty()) {
               // vvv how to return either on left
               !"SOME_CUSTOM_ERROR".raiseError()
           } else data.right()
           either
        }
I understand for a case like this where I have this requirement on the last step, I can return from outside the block, but just curious how to short-circuit from the middle of the block?
g
Thanks @stojan, but I am not clear on how can I solve when my return type (
data
in my example) is on
right
state, but based on it's value, I have to return a custom error so that the output of
either{}
block is on
CUSTOM_ERROR.left()
I feel this looks better n consistent with the style, but unnecessary wrapping and bind
Copy code
@Test
    fun `either fx`() = runBlocking {
        val result: Either<String, String> = either { // This casts the side-effect function into a suspend function.
            val id = !getSomethingFromDb(true)
            val data = !getSomethingElseFromNetwork(id)
            !(if (data.isEmpty()) "CUSTOM_ERROR".left() else data.right())
        }
        println(result)
    }
s
I would argue the unwrapping is unnecessary here
Copy code
val dataEither = getSomethingElseFromNetwork(id)
!dataEither.filterOrElse({!it.isEmpty()}, {CustomError})
to fail the
either
block, you need an
Either.Left
and you have to bind on it 🙂
g
ya, but I am trying to go totally imperative without using any functional operations
s
then you go with your approach 🙂
g
ya... thanks @stojan!
🙂
s
the
either
block is sugar for
map
and
flatMap
when you operate on a value, it's map when you do a
bind()
it's
flatMap
g
yes, I guess ur suggestion about
filterOrElse
can be said consistent in this style, as this comprehension is all about eliminating only the noise of
flatMap
I had something like this before
Copy code
val validate2Throwable: Validator<Egg, ValidationFailure> = {
    // Awesome DSL from arrow to work with either in an imperative way (Best of both worlds).
    either<ValidationFailure, Boolean> { // This casts the side-effect function into a suspend function.
        throwableRule2(it)
    }.filterOrElse(::identity) { TOO_LATE_TO_HATCH_2 }
}
126 Views