scala - 是否有 Scala 模式用于从一系列独立计算中收集错误消息?
问题描述
假设我有一系列需要在最后组合的独立计算:
def makeSauce(): Try[Sauce] = Success(Sauce("marinara"))
def makeCrust(): Try[Crust] = Failure(new RuntimeException("stale bread"))
def makeCheese(): Try[Cheese] = Failure(new IllegalArgumentException("moldy cheese"))
for {
sauce <- makeSauce()
crust <- makeCrust()
cheese <- makeCheese()
} yield {
Pizza(sauce, crust, cheese)
}
但是,如果我的任何计算失败,我想要一个描述所有失败的全面错误消息,而不仅仅是第一个。上面的代码没有做我想要的;它只向我展示了第一次失败("stale bread"
)。相反,它应该抛出一个结合其他两个的超级错误消息,这可能是一系列异常对象、一系列字符串错误消息,甚至只是一个巨大的串联字符串。
或者,可以将其组合成顶级Failure
对象,而不是抛出异常:
(for {
sauce <- makeSauce()
crust <- makeCrust()
cheese <- makeCheese()
} yield (sauce, crust, cheese)) match {
case Success((sauce, crust, cheese)) => Pizza(sauce, crust, cheese)
case Failure(e) => throw e
}
for-comprehension 和Try
here 仅用于说明;工作解决方案不必使用for
or Try
。但是,显然上述语法是富有表现力和干净的,几乎可以满足我的要求,因此理想情况下,解决方案会尽可能地坚持下去。
我怎样才能在 Scala 中实现这样的目标?
解决方案
验证是您正在寻找的。以猫为例。
import cats.data.Validated
import cats.implicits.catsSyntaxTuple3Semigroupal
def valid(input: String) = if (input.toIntOption.isEmpty) Validated.Invalid(s"$input is not a number")
else Validated.Valid(input.toInt)
def sumThreeNumbers(one:String, two:String, three: String) = (valid(one), valid(two), valid(three)).mapN((oneInt, twoInt, threeInt)=> oneInt + twoInt + threeInt)
sumThreeNumbers("1","2","3")
sumThreeNumbers("1","two","xxx")
//results
val res0: cats.data.Validated[String,Int] = Valid(6)
val res1: cats.data.Validated[String,Int] = Invalid(two is not a number.xxx is not a number.)
推荐阅读
- java - 如何创建一个可以将 keycloak 事件日志推送到 s3 的事件监听器?
- c# - 无法从程序集 Microsoft.AspNetCore.Routing Ver=3.1.7.0 加载类型 Microsoft.AspNetCore.Internal.EndpointRoutingApplicationBuilderExtensions
- laravel - 如何从 Laravel 中的嵌套关系中获取所有记录
- variables - 将两组变量关联为SPSS中的两个变量
- angular - Ngselect 中的项目未定义,我错过了什么?
- autofac - 如何指定 autofac 模块需要的外部依赖项
- c# - 通过 System.Reflection 获取类型:尝试强制转换时出错
- kubernetes - 在 Kubernetes 的 pod 中为单个容器使用非持久卷
- javascript - 无法使用 addEventListner 添加“活动”类
- javascript - 是否可以在浏览器中拦截第三方 POST 请求?