scala - 如何减少返回带有短路行为的函数的序列?
问题描述
以下面的例子为例(改编自猫的 Either 文档)。
三个验证函数依次应用,每个都返回一个 Either。如果任何函数的应用失败,则返回 Left 值。
object Validators {
def isBiggerThan5(i: Int): Either[Exception, Int] =
if (i > 5) Either.right(i)
else Either.left(new NumberFormatException(s"${i} is smaller than 5."))
def isSmallerThan20(i: Int): Either[Exception, Int] =
if (i < 20) Either.right(i)
else Either.left(new NumberFormatException(s"${i} is bigger than 20."))
def isEven(i: Int): Either[Exception, Int] =
if (i % 2 == 0) Either.right(i)
else Either.left(new NumberFormatException(s"${i} is not an even number."))
}
import Validators._
def magic(i: Int): Either[Exception, Int] =
isBiggerThan5(i).flatMap(isSmallerThan20).flatMap(isEven)
现在想象三个验证函数作为参数传递:
type Ops = Int => Either[Exception, Int]
def magic(ops: Seq[Ops])(s: String): Either[Exception, String] =
??? // How to apply ops in sequence with short circuit behavior?
println(magic(Seq(isBiggerThan5, isSmallerThan20, isEven)))
我们如何评估Seq[Ops]
一个接一个的短路行为?我玩过Seq.foldLeft
orSeq.reduce
但不太明白。
我对错误累积不感兴趣。它应该在第一个返回 Left 的验证器上失败。
解决方案
foldLeftM
应该管用。
import cats.syntax.all._
def verify(i: Int, ops: Vector[Ops]): Either[Exception, Int] =
ops.foldLeftM(i)((i, o) => o(i))
推荐阅读
- flutter - 每当底部导航栏项目更改时,FutureBuilder 都会重新加载
- excel - 连接除某些单元格以外的范围
- c++ - 在 VsCode 中使用 c++ 的问题(运行代码后在终端中打印错误)
- javascript - Firebase onSnapshot() 监听器...我能以某种方式从更改之前获取数据吗
- c# - 在 C# 中将字符串转换为 Double
- javascript - 如何使用 [index] 通过字符串值获取对象的属性
- java - 使用 Android Volley 的 HTTPS 字符串请求
- clang - Vim YouCompleteMe clang-completer 抱怨它找不到 Eigen(C++ 库)需要它的 'omp.h' 文件
- mysql - 截断和舍入在 MySQL 中给出比预期更多的小数
- mysql - Sequelize - 多对多关联 - 3 个外键