简体   繁体   中英

Returning NonEmptyList `sealed trait`'s w/ scalaz.Validation

Given the following code:

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)

However, I get a compile-time error when trying to put two InvalidPersonError 's into a NonEmptyList :

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

How can I combine the validation errors to fix this compile-time error?

You don't need to describe how to combine errors—that's taken care of by ValidationNel 's applicative functor via the Semigroup instance for NonEmptyList . The argument to the applicative builder should instead indicate how to create people:

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

This will accumulate errors correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM