如何使用Disjunction和Validation?

时间:2015-08-13 13:48:36

标签: scala validation scalaz

假设我需要使用下面列出的函数创建A的实例:

case class A(x: X, y: Y, z: Z)

val makeX: String => Error \/ X = ???
val makeY: String => Error \/ Y = ???
val makeZ: String => Error \/ Z = ???

val makeA: (String, String, String) => NonEmptyList[Error] \/ A = ???

由于我想积​​累makeXmakeYmakeZ的错误,我正在使用scalaz.Validation

val makeA: (String, String, String) => NonEmptyList[Error] \/ A = (s1, s2, s3) => {
  val x = makeX(s1).validation.toValidationNel
  val y = makeY(s2).validation.toValidationNel
  val z = makeZ(s3).validation.toValidationNel
  val a = (x |@| y |@| z)(A.apply _)
  a.disjunction
}

不幸的是.validation.toValidationNel看起来有点尴尬。你会如何改进这段代码?

1 个答案:

答案 0 :(得分:2)

使用帮助函数:

def vnel[A](a: Error \/ A) = a.validation.toValidationNel
你现在可以做到:

val makeA = (s1:String, s2:String, s3:String) => 
  (vnel(makeX(s1)) |@| vnel(makeY(s2)) |@| vnel(makeZ(s3)))(A.apply).disjunction