我编写了一个组合器,将ValidationNel[A, List[B]]
转换为ValidationNel[A, NonEmptyList[B]]
,当Failure
为空时返回List
。
def nonEmpty[A, B](valid : ValidationNel[A, List[B]], fail : => A) : ValidationNel[A, NonEmptyList[B]] =
valid match {
case Failure(f) => f.failure[NonEmptyList[B]]
case Success(s) =>
if (!s.isEmpty) NonEmptyList(s.head, s.tail:_*).successNel[A]
else fail.failureNel[NonEmptyList[B]]
}
有更好的方法吗?
答案 0 :(得分:2)
我们可以通过两种方式改进您的nonEmpty
功能:
List
转换为Option[NonEmptyList]
toNel
。ValidationNel
上的模式匹配与flatMap
类似,但Validation
没有flatMap
操作,因为它是 Applicative < / em>而不是 Monad 。 Scalaz提供了一些简单的函数来转换Validation
和\/
(也称为析取),因此我们可以使用\/
&#39; s flatMap
。您的nonEmpty
功能可能如下所示:
import scalaz.{ValidationNel, NonEmptyList}
import scalaz.syntax.std.list._
import scalaz.syntax.std.option._
import scalaz.syntax.nel._
def nonEmpty[A, B](valid: ValidationNel[A, List[B]],
fail: => A): ValidationNel[A, NonEmptyList[B]] =
valid.disjunction.flatMap(_.toNel toRightDisjunction fail.wrapNel).validation
您可以将其用作:
import scalaz.syntax.validation._
nonEmpty(List(1,2).success, "test")
// scalaz.ValidationNel[String,scalaz.NonEmptyList[Int]] =
// Success(NonEmptyList(1, 2))
nonEmpty(List().success, "list is empty")
// scalaz.ValidationNel[String,scalaz.NonEmptyList[Nothing]] =
// Failure(NonEmptyList(list is empty))