gpt4 book ai didi

scala - 编写 Scalaz 验证

转载 作者:行者123 更新时间:2023-12-03 21:17:09 24 4
gpt4 key购买 nike

我想使用 Scalaz 进行验证,并且希望能够在不同的上下文中重用验证函数。顺便说一句,我对 Scalaz 完全陌生。

假设我有这些简单的检查:

def checkDefined(xs: Option[String]): Validation[String, String] =
xs.map(_.success).getOrElse("empty".fail)

def nonEmpty(str: String): Validation[String, String] =
if (str.nonEmpty) str.success else "empty".fail

def int(str: String): Validation[String, Int] = ...

我希望能够编写验证,其中一个的输出被馈送到另一个。我可以使用 flatMap 轻松做到这一点或通过理解,但感觉必须有比这更好的方法。
for {
v1 <- checkDefined(map.get("foo"))
v2 <- nonEmpty(v1)
v3 <- int(v2)
v4 <- ...
} yield SomeCaseClass(v3, v4)

或者
val x1 = checkDefined(map get "foo").flatMap(nonEmpty).flatMap(int)
val x2 = check(...)

// How to combine x1 and x2?

Scalaz 专家有什么想法吗?

最佳答案

除了@oxbow_lakes 建议的解决方案,您还可以使用 Kleisli 组合。

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> def f: Int => Validation[String, Int] = i => if(i % 2 == 0) Success(i * 2) else Failure("Odd!")
f: Int => scalaz.Validation[String,Int]

scala> def g: Int => Validation[String, Int] = i => if(i > 0) Success(i + 1) else Failure("Not positive!")
g: Int => scalaz.Validation[String,Int]

scala> type Va[+A] = Validation[String, A]
defined type alias Va

scala> import Validation.Monad._
import Validation.Monad._

scala> kleisli[Va, Int, Int](f) >=> kleisli[Va, Int, Int](g)
res0: scalaz.Kleisli[Va,Int,Int] = scalaz.Kleislis$$anon$1@4fae3fa6

scala> res0(11)
res1: Va[Int] = Failure(Odd!)

scala> res0(-4)
res2: Va[Int] = Failure(Not positive!)

scala> res0(4)
res3: Va[Int] = Success(9)
A => M[B] 类型的函数在哪里 M : Monad称为克莱斯利箭。

您可以组合两个 Kleisli 箭头 A => M[B]B => M[C]得到一个箭头 A => M[C]使用 >=>运算符(operator)。这被称为 Kleisli 组合。

表达式 kleisli(f) >=> kleisli(g) >=> kleisli(h)相当于 x => for(a <- f(x); b <- g(a); c <- h(b)) yield c ,减去不必要的本地绑定(bind)。

关于scala - 编写 Scalaz 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9428174/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com