gpt4 book ai didi

scala - 展平嵌套 Scalaz 验证

转载 作者:行者123 更新时间:2023-12-02 08:37:48 25 4
gpt4 key购买 nike

我对 scalaz 还很陌生,我已经从验证开始了。

我有一些以下形式的验证函数:

def validateXyz(...): ValidationNEL[String, String] = ...

然后,我使用应用样式来组合多个验证,然后调用另一个也返回验证的函数:

(validateXyz(...) |@| validateAbc(...)) { (first, second) =>
otherFunction(first, second)
}

哪里,

def otherFunction(first: String, second: String): ValidationNEL[String, String] = ...

但是,当调用上述方法时,结果类型是:

val result: ValidationNEL[String, ValidationNEL[String, String]] = ...

我可以通过使用两个函数对结果调用折叠来解压它,第一个函数仅将 NEL 传播为失败,第二个函数仅传播其参数:

def propagateF(result: NonEmptyList[String]): ValidationNEL[String, String] = result.fail
def propagateV(result: ValidationNEL[String, String]) = result

result.fold(propagateF, propagateV)
// result type: ValidationNEL[String, String]

这可以工作并返回正确的类型和结果。然而,这感觉不是正确的解决方案,所以我一定错过了一些东西。我需要做什么才能避免最后出现这种可怕的折叠?

最佳答案

您在这里寻找的是单子(monad)join

问题是 Validation 本身并不是真正的 monad,因为错误端带有一个 Semigroup 结构,该结构无法被 Monad 保存。但如果需要,您可以随时进入 Either monad。此功能由 flatMap 提供。

(validateXyz(...) |@| validateAbc(...))(otherFunction).flatMap(x => x)

如果外部发生错误,结果将是该错误。如果成功内部有错误,结果将是内部错误。否则结果就会成功。请注意内部和外部都不可能出现错误。这就是为什么如果您想合并错误,则必须使用 Applicative 而不是 Monad

关于scala - 展平嵌套 Scalaz 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11173643/

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