如何编写返回验证的函数? [英] How to compose functions that return Validation?
问题描述
这是我之前的问题的后续
假设我有两个验证函数,如果输入有效则返回输入,否则返回错误消息.
Suppose I have two validating functions that return either the input if it is valid or the error messages if it is not.
type Status[A] = ValidationNel[String, A]
val isPositive: Int => Status[Int] =
x => if (x > 0) x.success else s"$x not positive".failureNel
val isEven: Int => Status[Int] =
x => if (x % 2 == 0) x.success else s"$x not even".failureNel
还假设我需要验证 case class X
的一个实例:
Suppose also that I need to validate an instance of case class X
:
case class X(x1: Int, // should be positive
x2: Int) // should be even
更具体地说,我需要一个函数 checkX: X =>状态[X]
.此外,我想将 checkX
编写为 isPositive
和 isEven
的 composition.
More specifically I need a function checkX: X => Status[X]
. Moreover, I'd like to write checkX
as a composition of isPositive
and isEven
.
val checkX: X => Status[X] =
({x => isPositive(x.x1)} |@| {x => isEven(x.x2)}) ((X.apply _).lift[Status])
有意义吗?
你会如何将 checkX
写成 isPositive
和 isEven
的组合?
Does it make sense ?
How would you write checkX
as a composition of isPositive
and isEven
?
推荐答案
有很多方法可以写这个,但我喜欢以下几点:
There are lots of ways to write this, but I like the following:
val checkX: X => Status[X] = x => isPositive(x.x1).tuple(isEven(x.x2)).as(x)
或者:
val checkX: X => Status[X] =
x => isPositive(x.x1) *> isEven(x.x2) *> x.point[Status]
关键点是您希望仅针对它们的效果"运行两个验证,然后在新上下文中返回原始值.正如您自己的实现所示,这是一个完全合法的应用操作.只是有一些更好的编写方式.
The key point is that you want to run the two validations only for their "effects" and then return the original value in the new context. This is a perfectly legitimate applicative operation, as your own implementation shows. There are just some slightly nicer ways to write it.
这篇关于如何编写返回验证的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!