6

I'm programming using the functional library arrow-kt (formerly known as kategory). I'm using Either monad to aggregate errors or success information of an api call. I got myself into a state (which shouldn't happen in the first place) in which I have a nestet Either monads. I'm trying to flatten the structure to get the inner monad. The documentation is very limited and I couldn't find a way to do It.

Here's an example of a nested Either monad that I would like to flatten:

Either.right(Either.right(Either.left("error")))
MaxG
  • 1,079
  • 2
  • 13
  • 26
  • Quick response: Either has a flatMap method on it, but you should never be creating the nested. Use fold, flatMap, flatMapLeft to ensure you only ever end up one-level deep. If you have code examples, I may be able to help more. – Mikezx6r Feb 12 '18 at 18:51
  • the `flatMap` is throwing away the `left` values. I want to preserve them all (something like `fold` with collections). About the code, I'll have to paste pretty reasonable amount of code... I'll do It soon. – MaxG Feb 12 '18 at 20:38
  • isn't it you should get `Either.left()` as the return value, nothing should be calculated since you got an error I think – Lamour Feb 12 '18 at 22:31

1 Answers1

17

You may flatten such a structure with flatten:

import arrow.core.*
import arrow.typeclasses.*

val result = Either.right(Either.right(Either.left("error")))
Either.monad<String>().flatten(result)
// keep flattening until you are happy with the result
// Right(b=Left(a=error))

Or just flatMap:

import arrow.core.*
import arrow.typeclasses.*

val result = Either.right(Either.right(Either.left("error")))
result.flatMap { it.flatMap { it } }
// Left(a=error)

The fact that you ended up with such nested structure probably means that you are not using the right datatype or wrong abstraction at some point in your program as that is kind of a useless value.

If you wish to preserve the left values as indicated in your comment I think a more suitable datatype would be Validated which allows for error accumulation as demonstrated here http://arrow-kt.io/docs/datatypes/validated/

Alternatively Either#fold can help you contemplate both cases and coalesce then into whatever value you wish.

I'm assuming you already run into these where most of this stuff is explained but just in case some useful links that will help you model this with Arrow

Additionally feel free to swing by our chat channels if you need a more interactive experience with the maintainers and other contributors than SO where we frequently help people of all levels learning FP and Arrow.

Cheers!

Marek J
  • 1,364
  • 8
  • 18
  • 33
  • Thanks for the quick reply! I'll use `flatten` for the meantime and check the `Validated` later. – MaxG Feb 13 '18 at 00:19