Scala 如何使用以下任一方法产生所有错误(失败)

Scala 如何使用以下任一方法产生所有错误(失败),scala,error-handling,either,Scala,Error Handling,Either,我对Scala完全陌生。好的,或者封装了故障处理,允许在不重复编写样板代码的情况下进行链式操作。它还允许断路器继续执行。但这可能并不总是我想要的。e、 g.对于以下代码,如果name和age都无效,则makePerson函数不会同时返回这两个错误 你们能建议一条路吗 案例类人员(姓名:姓名,年龄:年龄) 密封类名称(val值:字符串) 密封类年龄(val值:Int) 案例类人员(姓名:姓名,年龄:年龄){ } 密封类名称(val值:字符串) 密封类年龄(val值:Int) 对象人{ def ma

我对Scala完全陌生。好的,
或者
封装了故障处理,允许在不重复编写样板代码的情况下进行链式操作。它还允许断路器继续执行。但这可能并不总是我想要的。e、 g.对于以下代码,如果
name
age
都无效,则
makePerson
函数不会同时返回这两个错误

你们能建议一条路吗

案例类人员(姓名:姓名,年龄:年龄)
密封类名称(val值:字符串)
密封类年龄(val值:Int)
案例类人员(姓名:姓名,年龄:年龄){
}
密封类名称(val值:字符串)
密封类年龄(val值:Int)
对象人{
def makeName(名称:字符串):或者[String,name]={
if(name==“”| | name==null)左(“name为空”);else右(新名称(name))
}
def makeAge(age:Int):或者[String,age]={
如果(年龄<0)左(“年龄超出范围”),否则右(新年龄(年龄))
}
def makePerson(名称:String,年龄:Int):或者[String,Person]={
mkName(name).map2(mkAge(age))(Person(u,uu))
}
}
defmap2[EE>:E,B,C](B:earth[EE,B])(f:(A,B)=>C):earth[EE,C]={
val func=(aa:A)=>b.map(bb=>f(aa,bb))
此.flatMap(func)
}
def flatMap[EE>:E,B](f:A=>或[EE,B]):或[EE,B]=此匹配{
案例左侧(e)=>左侧(e)
案例右侧(a)=>f(a)
}

以下是使用@Luis建议的
验证
并行
进行错误累积的示例:

已验证
无效
案例中,我们看到所有错误都是累积的

并行

左侧
案例中,我们看到所有错误都是累积的。

从技术上讲,您不能。至少不使用标准方法。您可以写入所有锅炉板以返回一个
或[List[Error],Value]
。然而,如果你对其他选择持开放态度,我建议你使用。您有两个选项,一个是使用而不是
(设计用于此1),另一个是使用
的实例(反过来在引擎盖下使用
已验证的
).@LuisMiguelMejíaSuárez你应该把它当作answer@LuisMiguelMejíaSuárez只在评论部分工作:)@Lasf我有时会用一个例子来补充他的评论,不公平地收集他的选票,对此我深表歉意。@MarioGalic symbiosis!你知道,通过提供高质量的答案,你不应该感到难过;)-大多数时候我都写不出完整的答案,要么是因为在电话上,要么就是没有时间。但是,因为我只是想帮忙,所以我试着写一些有用的评论。所以我真的很高兴人们发现他们很有价值,而且其他人可以提供好的答案顺便说一句,现在我真的不在乎积分,我的第一个1K很酷,当时我也是第一个,我记得我在我所有的社交媒体上发布了!但是,在那之后不久,我意识到我真的不在乎要点,而在乎帮助的感觉。
import cats.data.ValidatedNec
import cats.implicits._

case class Person(name: Name, age: Age)
case class Name(value: String)
case class Age(value: Int)

object validatedPerson extends App {
  private def validateName(name: String): ValidatedNec[String, Name] =
    if (name == "" || name == null) "Name is empty.".invalidNec else Name(name).validNec

  private def validateAge(age: Int): ValidatedNec[String, Age] =
    if (age < 0) "Age is out of range.".invalidNec else Age(age).validNec


  def validatePerson(name: String, age: Int): ValidatedNec[String, Person] = {
    (validateName(name), validateAge(age)).mapN(Person)
  }

  println(validatePerson(name = "Joe", age = 21))
  println(validatePerson(name = "", age = -42))
}
Valid(Person(Name(Joe),Age(21)))
Invalid(Chain(Name is empty., Age is out of range.))
import cats.data.{EitherNel, NonEmptyList}
import cats.instances.parallel._
import cats.syntax.parallel._

object parValidatedPerson extends App {
  private def validateName(name: String): EitherNel[String, Name] =
    if (name == "" || name == null) Left(NonEmptyList.one("Name is empty.")) else Right(Name(name))

  private def validateAge(age: Int): EitherNel[String, Age] =
    if (age < 0) Left(NonEmptyList.one("Age is out of range.")) else Right(Age(age))


  def validatePerson(name: String, age: Int): Either[NonEmptyList[String], Person] = {
    (validateName(name), validateAge(age)).parTupled.map(Person.tupled)
  }

  println(validatePerson(name = "Joe", age = 21))
  println(validatePerson(name = "", age = -42))
}

Right(Person(Name(Joe),Age(21)))
Left(NonEmptyList(Name is empty., Age is out of range.))