1

I am really struggeling with the Validated types of the arrow library.

What I don't get is: why is there no flatMap or flatten when working with Validated?

I am coming from the "Either world" where this is no issue at all. But I need multiple errors combined, so my core validation type is ValidatedNel<Error, Data> in the end.

In my code example, I have a function that produces an Either - I use these low-level steps to either create an element I need or an error.

But to do a correct validation with all accumulated errors combined, I sooner or later need ValidatedNel types.

fun readData(): Either<Error, DataA> = ...
fun DataA.validate(): ValidatedNel<Error, DataB> = ...

[...]
// here I need to fold to get my one Error to a Nel and to process the data to another type - this looks so ugly!
val validated = readData().fold( { it.invalidNel() }, DataA::validate)

What I instead would like to have is:

fun readData(): ValidatedNel<Error, DataA> = ...

// ...
val validated = readData.flatMap(DataA::validate)

I simply don't understand why the Validation types do not support a simple operation like flatMap.

Does anybody know what to do?

Zordid
  • 10,451
  • 11
  • 42
  • 58

1 Answers1

2

Validation only requires Applicative and Monoid; it does not require Monad. Or, plainly speaking: things that validate data can occur in any order (Applicative) and multiple validations accumulate errors, usually by concatenating lists of errors (Monoid). Validations are usually not dependent on each other or require a specific sequence of computations (Monad).

Dependent validations are probably better expressed as an Either chain then converted to a Validation after the chain completes.

The Scala Cats library has a good explanation here: https://typelevel.org/cats/datatypes/validated.html

BobG
  • 2,113
  • 17
  • 15