如何编写返回验证的函数? [英] How to compose functions that return Validation?

查看:43
本文介绍了如何编写返回验证的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我之前的问题的后续

假设我有两个验证函数,如果输入有效则返回输入,否则返回错误消息.

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 编写为 isPositiveisEvencomposition.

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 写成 isPositiveisEven组合?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆