返回NonEmptyList`sealed trait`&w; scalaz.Validation

时间:2015-06-16 19:40:25

标签: scala scalaz applicative

给出以下代码:

object Person {

    override def makePerson(name: String, age: Int, gender: Gender): 
              Validation[NonEmptyList[InvalidPersonError], Person] =
        (validateName(name) |@| validateAge(age)) {_ ++ _} 

    private def validateName(name: String): 
       Validation[NonEmptyList[InvalidPersonError], String] = 
        if(name.nonEmpty) name.successNel else InvalidName.failureNel

    private def validateAge(age: Int): Validation[NonEmptyList[InvalidPersonError], Int] = 
        if(age >= 0) age.successNel else InvalidAge.failureNel

    sealed trait Gender
    case object Male extends Gender
    case object Female extends Gender

    sealed trait InvalidPersonError
    case object InvalidName extends InvalidPersonError
    case object InvalidAge extends InvalidPersonError
}

case class Person(name: String, age: Int, gender: Person.Gender)

但是,在尝试将两个InvalidPersonError放入NonEmptyList时出现编译时错误:

[error] ...\Person.scala:9: type mismatch;
[error]  found   : Int
[error]  required: scala.collection.GenTraversableOnce[?]
[error]                 (validateName(name) |@| validateAge(age)) {_ ++ _}
[error]            

如何组合验证错误来修复此编译时错误?

1 个答案:

答案 0 :(得分:3)

您无需通过ValidationNel Semigroup实例来描述如何合并错误 - 由NonEmptyList的应用仿函数处理。应用程序构建器的参数应该指示如何创建人员:

def makePerson(name: String, age: Int, gender: Gender):
  Validation[NonEmptyList[InvalidPersonError], Person] =
    (validateName(name) |@| validateAge(age))(Person(_, _, gender))

这会正确累积错误。