如何转换 List[ValidationNel[A, Option[B]]]
How to transform List[ValidationNel[A, Option[B]]]
我需要一个组合器将 List[ValidationNel[A, Option[B]]]
转换为 ValidationNel[A, List[B]]
以对验证进行排序,如果成功,则将这些废话弄平。
这是代码:
def sequenceAndFlatten[A,B](valid: List[ValidationNel[A, Option[B]]]) : ValidationNel[A, List[B]] =
valid.sequenceU.map(_.flatten)
有没有更好的方法?
我们可以使用 traverseM
:
引用 traverseM
文档(join
是 flatten
的 Scalaz 名称):
A version of traverse where a subsequent monadic join is applied to the inner result.
sequence
等同于 traverse(identity)
.
所以 traverseM(identity)
应该类似于 sequence.map(_.flatten)
,但是 flatten
使用从 Option
到 List
的隐式转换,而 Scalaz 只会展平单子相同的类型,所以我们需要将 Option
显式转换为 List
:traverseM(_.map(_.toList))
.
使用 traverseM
的一个问题是我们不能像使用 sequenceU
一样使用 Unapply
。我们需要给编译器一些帮助并自己指定类型参数(使用类型 lambda)。
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))
这与您的 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))
我需要一个组合器将 List[ValidationNel[A, Option[B]]]
转换为 ValidationNel[A, List[B]]
以对验证进行排序,如果成功,则将这些废话弄平。
这是代码:
def sequenceAndFlatten[A,B](valid: List[ValidationNel[A, Option[B]]]) : ValidationNel[A, List[B]] =
valid.sequenceU.map(_.flatten)
有没有更好的方法?
我们可以使用 traverseM
:
引用
traverseM
文档(join
是flatten
的 Scalaz 名称):A version of traverse where a subsequent monadic join is applied to the inner result.
sequence
等同于traverse(identity)
.
所以 traverseM(identity)
应该类似于 sequence.map(_.flatten)
,但是 flatten
使用从 Option
到 List
的隐式转换,而 Scalaz 只会展平单子相同的类型,所以我们需要将 Option
显式转换为 List
:traverseM(_.map(_.toList))
.
使用 traverseM
的一个问题是我们不能像使用 sequenceU
一样使用 Unapply
。我们需要给编译器一些帮助并自己指定类型参数(使用类型 lambda)。
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))
这与您的 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))