假设我需要使用下面列出的函数创建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 = ???
由于我想积累makeX
,makeY
和makeZ
的错误,我正在使用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
看起来有点尴尬。你会如何改进这段代码?
答案 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