简体   繁体   中英

How to transform List[ValidationNel[A, Option[B]]]

I need a combinator to transform a List[ValidationNel[A, Option[B]]] into a ValidationNel[A, List[B]] to sequence the validation and, in case of success, flatten that crap.

Here is the code :

  def sequenceAndFlatten[A,B](valid: List[ValidationNel[A, Option[B]]]) : ValidationNel[A, List[B]] =
    valid.sequenceU.map(_.flatten)

Is there a better way ?

We can use traverseM :

  • Quoting the traverseM documentation ( join is the Scalaz name for flatten ) :

    A version of traverse where a subsequent monadic join is applied to the inner result.

  • sequence is the same as traverse(identity) .

So traverseM(identity) should be similar to sequence.map(_.flatten) , but flatten uses an implicit conversion from Option to List while Scalaz will only flatten monads of the same type, so we need to convert the Option to List explicitly: traverseM(_.map(_.toList)) .

A problem with using traverseM is that we cannot use Unapply , like with your sequenceU . We will need to give the compiler some help and specify the type parameters (using a type lambda) ourselves.

import scalaz.ValidationNel
import scalaz.std.list._
import scalaz.syntax.traverse._

def seqFlat[A,B](valid: List[ValidationNel[A, Option[B]]]): ValidationNel[A, List[B]] =
  valid.traverseM[({type l[x] = ValidationNel[A, x]})#l, B](_.map(_.toList))

Which gives the same result as your sequenceAndFlatten :

import scalaz.std.option._
import scalaz.syntax.std.option._
import scalaz.syntax.validation._

val validations = 
  List(1.some.successNel[String], 2.some.successNel, none[Int].successNel)

sequenceAndFlatten(validations)
// scalaz.ValidationNel[String,List[Int]] = Success(List(1, 2))

seqFlat(validations)
// scalaz.ValidationNel[String,List[Int]] = Success(List(1, 2))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM