https://kotlinlang.org logo
Title
e

Emil Kantis

04/27/2023, 1:37 PM
Using Arrow 1.2.0-RC, what's the most elegant way to handle something like this?
val squares = (1..10).mapOrAccumulate { squareService.square(it).bind() } // EitherNel<E1, Square>
val roots = (1..10).mapOrAccumulate { rootService.root(it).bind() } // EitherNel<E2, Root>

zipOrAccumulate(
  { // check squares? },
  { // check roots? },
  { ensureSomethingElse() },
) { validSquares, validRoots, somethingElse -> 
   // ... 
}
s

simon.vergauwen

04/27/2023, 2:18 PM
So you need to align E1 and E2? Otherwise you can just call
bind
e

Emil Kantis

04/27/2023, 2:20 PM
yes, I thought I'd do that
like bake it into an aggregated problem,
data class InvalidOperation(val problems: List<String>) 

InvalidOperation(listOf(invalidRoots.map { "Invalid root: $it" } + invalidSquares.map { "Invalid square: $it }))
s

simon.vergauwen

04/27/2023, 2:35 PM
With
Either
I would just use
mapLeft + bind
.
val squares = (1..10).mapOrAccumulate { squareService.square(it).bind() } // EitherNel<E1, Square>
val roots = (1..10).mapOrAccumulate { rootService.root(it).bind() } // EitherNel<E2, Root>

zipOrAccumulate(
  { squares.mapLeft { }.bind() },
  { roots.mapLeft { }.bind() },
  { ensureSomethingElse() },
) { validSquares, validRoots, somethingElse -> 
   // ... 
}
There is also:
Either.zipOrAccumulate(
  squares.mapLeft { },
  roots.mapLeft { },
  either { ensure(...) { } }
) { a, b, c -> }
e

Emil Kantis

04/27/2023, 6:39 PM
Thanks Simon 🙌