scala - Scala - 如何使用来自猫的 Validated monad 验证列表中的每个字符串?
问题描述
我有一个列表Strings
,我需要验证它们是否与某些模式匹配:
def validate(strings: List[String]): Either[WrongStringError, List[String]] = {
strings.foreach(s => checkString(s))
Right(strings)
}
private def checkString(s: String): Validated[WrongStringError, String] = {
val pattern = .... //some regex
Either.catchNonFatal(s.matches(pattern))
.left
.map(_ => WrongStringError(s"Given string: ${s} is not valid."))
}.toValidated
但是,我想要实现的是将所有错误汇总在一起。例如,如果 5 个字符串中有 3 个不正确,我想将错误返回给用户。我想过使用Validated
monad fromcats
但我没有得到结果。如何验证字符串列表并返回不正确的错误列表?
解决方案
我想过使用来自猫的 Validated monad,但我没有得到结果。
Validated
好吧,诸如(或任何 FP 数据结构)之类的东西的想法是将值组合在一起。
但是,您在这里没有编写任何东西,您只是在调用 a foreach
,因此如果发生故障,您甚至不会收到错误,您将始终收到 a Right
。
此外,如果要收集所有错误,则需要使用某种(非空)容器,例如NonEmptyChain
.
最后,我有一个值的集合和将这些值转换为有效值的函数的这种常见模式,我想将所有这些效果收集/组合成一个列表的单个效果称为traverse
.
加分点,这种使用同构效果类型的常见模式看起来与我的正常效果完全一样,只是为了提供不同的(并行)行为,它只是一个Applicative
而不是一个,如此普遍,以至于猫引入了类型类和组合器(例如)以避免样板。Monad
Parallel
parTraverse
无论如何,这就是代码的样子:
import cats.data.NonEmptyChain
import cats.syntax.all._
type Error = String
def validate(strings: List[String]): Either[NonEmptyChain[Error], List[String]] =
strings.parTraverse { s =>
checkString(s).toEitherNec
}
def checkString(s: String): Either[Error, String] = {
val pattern = ""
Either.cond(
test = s.matches(pattern),
right = s,
left = "Given string: ${s} is not valid."
)
}
顺便说一句,我建议您更多地学习 FP。
我可能会向您推荐 Rob Norris 的演讲“Functional Programming with Effects”和(免费)书籍“Scala with Cats”。
推荐阅读
- php - 用于处理类似“test-12-1”的字符串的正则表达式 (php)
- javascript - 从 webpack 导入后,Vue 应用程序中的 MomentJS 警告
- java - Timer 和 Runnable 有什么区别?
- python - 在 tkinter 条目小部件中输入的数据包含“NoneType”对象并且没有属性“get”
- java - 如何优化初学者 HackerEarth 代码
- azure - 如何在新的 Azure Cloud Power Shell 'Az' 中运行 Azure 的 Get-AzureServiceAntimalwareConfig cmdlet
- ruby - 未定义的方法“gsub”,变量可能存在问题
- android - 类型不匹配。必需:NotificationCompat.Style,找到:Notification.BigPictureStyle
- javascript - 它增加了第二个 } 并且不将 1 添加到级别
- javascript - 以特殊顺序对数组进行排序