In ScalaZ, what is the idiomatic way to convert an Option[Validation[E, A]]
to a Validation[E, Option[A]]
?
For example, in the following hypothetical code:
def convert(x: Option[Validation[E, A]]): Validation[E, Option[A]] =
/* ??? */
def validateThing(thing: A): Validation[E, A] =
/* whatever */
def exampleUseCase(maybeThing: Option[Thing]): Validation[E, Option[Thing]] = {
val validated: Option[Validation[E, Thing]] = a.map(validateThing(_))
// ...
val result: Validation[E, Option[Thing]] = convert(validated)
result
}
what would the implementation of convert
look like in idiomatic ScalaZ?
I can see two possible solutions here. Probably the easiest one using pattern matching on the argument, example:
def convert[A](v: Option[Validation[Throwable, A]]): Validation[Throwable, Option[A]] = {
v match {
case None => Validation.success(None)
case Some(valid) => valid.map(Some(_))
}
}
For Scalaz based solution, i was thinking about sequence, this way you need to use ValidationNel instead of Validation, to aggregate possible issues, the you can implement convert
with Traversable
:
def convert[A](v: Option[ValidationNel[Throwable, A]]): ValidationNel[Throwable, Option[A]] =
Traverse[Option].sequenceU(v)
Please note that in fact i'm using sequenceU
instead of just sequence
, it's nothing more than internal Scalaz magic for proper type inference, cause Validation has two type parameters. Hope it helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With