返回带有 scalaz.Validation 的 NonEmptyList `sealed trait`
Returning NonEmptyList `sealed trait`'s w/ scalaz.Validation
给定以下代码:
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]
如何结合验证错误来修复此编译时错误?
您不需要描述如何组合错误——这由 ValidationNel
的应用函子通过 NonEmptyList
的 Semigroup
实例处理。 applicative builder 的参数应该指示如何创建人:
def makePerson(name: String, age: Int, gender: Gender):
Validation[NonEmptyList[InvalidPersonError], Person] =
(validateName(name) |@| validateAge(age))(Person(_, _, gender))
这将正确累积错误。
给定以下代码:
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]
如何结合验证错误来修复此编译时错误?
您不需要描述如何组合错误——这由 ValidationNel
的应用函子通过 NonEmptyList
的 Semigroup
实例处理。 applicative builder 的参数应该指示如何创建人:
def makePerson(name: String, age: Int, gender: Gender):
Validation[NonEmptyList[InvalidPersonError], Person] =
(validateName(name) |@| validateAge(age))(Person(_, _, gender))
这将正确累积错误。