gpt4 book ai didi

validation - Scalaz 验证与应用仿函数 |@|不工作

转载 作者:行者123 更新时间:2023-12-04 14:02:01 25 4
gpt4 key购买 nike

我正在尝试在我的应用程序中使用 Scalaz 7 验证。但是,我在获取 |@| 时遇到问题应用仿函数来合并我的失败。这是我的代码:

type ValidationResult = ValidationNel[String, Unit]

def validate[A: ClassTag](instance: A, fieldNames: Option[Seq[String]] = None): ValidationResult = {
val fields = classTag[A].runtimeClass.getDeclaredFields
val fieldSubset = fieldNames match {
case Some(names) => fields.filter { field => names.contains(field.getName) }
case None => fields
}
fieldSubset.map {
field => field.getAnnotations.toSeq.map {
field.setAccessible(true)
val (name, value) = (field.getName, field.get(instance))
field.setAccessible(false)
annotation => annotation match {
case min: Min => minValidate(name, value, min.value())
case size: Size => sizeValidate(name, value, size.min(), size.max())
}
}
}.flatten[ValidationResult].foldLeft(().successNel[String])(_ |@| _)
}
minValidatesizeValidate函数只返回 ValidationResults .

问题是,这段代码无法编译。错误信息是:
Type mismatch, expected F0.type#M[NotInferedB], actual: ValidationResult

我不知道这意味着什么……我需要给 Scala 更多的类型信息吗?

我想要完成的是,如果所有字段都是 successNel s,然后返回那个,否则返回所有 failureNel 的组合s。

|@|自 Scalaz 的先前版本以来发生了变化?因为即使我做了类似的事情:
().successNel |@| ().successNel

我犯了同样的错误。

更新

我开始浏览 Scalaz 源代码,我找到了 +++这似乎做我想做的。
+++有什么区别和 |@| ?

最佳答案

Scalaz 的 applicative builder 语法 ( |@| ) 为您提供了一种将函数“提升”为 applicative functor 的方法。假设我们有以下结果,例如:

val xs: ValidationNel[String, List[Int]] = "Error!".failNel
val ys: ValidationNel[String, List[Int]] = List(1, 2, 3).success
val zs: ValidationNel[String, List[Int]] = List(4, 5).success

我们可以将列表连接函数( ++ )提升到 Validation像这样:
scala> println((ys |@| zs)(_ ++ _))
Success(List(1, 2, 3, 4, 5))

scala> println((xs |@| ys)(_ ++ _))
Failure(NonEmptyList(Error!))

scala> println((xs |@| xs)(_ ++ _))
Failure(NonEmptyList(Error!, Error!))

这种语法有点奇怪——例如,它与你在 Haskell 中将函数提升到应用仿函数的方式非常不同,它的设计主要是为了胜过 Scala 相当愚蠢的类型推断系统。见 my answer hereblog post here更多讨论。

奇怪的部分是 xs |@| ys它本身并没有真正的意义——它本质上是一个参数列表,它等待应用于一个函数,它将提升到它的应用仿函数并应用于自身。
+++Validation是一种更简单的生物——它只是 Semigroup 的加法运算类型的实例(请注意,您可以在此处等效地使用 Scalaz 的半群运算符 |+| 代替 +++ )。你给它两个 Validation结果与匹配的半群类型,它给你另一个 Validation ——不是什么可怕的 ApplyOps事物。

作为旁注,在这种情况下, Validation 的加法运算的半群与右侧提升到 Validation的半群操作相同:
scala> (xs |+| ys) == (xs |@| ys)(_ |+| _)
res3: Boolean = true

然而,情况并非总是如此(例如,它不适用于 \/ ,其中半群累积错误但应用仿函数没有)。

关于validation - Scalaz 验证与应用仿函数 |@|不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17711895/

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