博客
关于我
Scalaz(20)-Monad: Validation-Applicative版本的Either
阅读量:463 次
发布时间:2019-03-06

本文共 3584 字,大约阅读时间需要 11 分钟。

Scalaz中的Validation:深入理解其功能与应用

Scalaz中的Validation是一个强大的功能,用于处理数据验证和错误处理。它在很多方面与 Scala的标准库/(即Either)有相似之处,但又有显著的区别。Validation不仅提供了基本的验证功能,还通过其Applicative特性,允许同时处理多个Validation,并返回多个异常信息。以下将深入探讨Validation的核心功能、与/的区别以及其实际应用场景。

Validation的核心概念

Validation在Scalaz中定义为:

sealed abstract class Validation[+E, +A] extends Product with Serializable {
// 其他定义已省略...
def isSuccess: Boolean = this match {
case Success(_) => true
case Failure(_) => false
}
// 其他方法已省略...
}

Validation有两个状态:Success和Failure。Success表示验证成功,返回一个值;Failure表示验证失败,返回一个异常信息。与/(Either)相比,Validation的主要特点在于它支持多个异常信息的返回。

Validation与/的区别

虽然Validation和/在某些方面非常相似,但它们在处理多个异常信息时有显著差异。与/不同之处在于,Validation通过其Applicative特性,可以在同一个操作中处理多个Validation,并返回多个异常信息。

操作符API

Validation提供了丰富的操作符API,包括:

  • orElse:如果当前Validation是成功,则返回当前Validation;如果失败,则返回另一个Validation。
  • swap:交换Validation的状态,即将Success转换为Failure,反之亦然。
  • ap:应用函数在当前Validation的成功路径上,同时处理可能的错误。

这些操作符使得Validation在处理复杂的验证逻辑时非常灵活。

Validation的状态定义

Validation的两个状态定义如下:

final case class Success[A](a: A) extends Validation[Nothing, A]
final case class Failure[E](e: E) extends Validation[E, Nothing]
  • Success表示验证成功,携带一个值。
  • Failure表示验证失败,携带一个异常值。

这些状态定义使得Validation能够方便地处理成功和失败两种情况。

Validation的Monad特性

Validation是一个Monad,它支持在for-comprehension中实现 Failure立即退出的功能。例如:

for {
a <- Success(3)
b <- Success(2)
} yield a + b

上述代码返回一个Success(5)的Validation。

如果其中任何一个步骤返回Failure,则整个Validation也会返回Failure。

注入方法

Scalaz为Validation提供了丰富的注入方法,例如:

  • success:创建一个成功的Validation。
  • failure:创建一个失败的Validation。
  • successNel:创建一个携带NonEmptyList的成功Validation。
  • failureNel:创建一个携带NonEmptyList的失败Validation。

这些方法使得开发者能够更方便地构建Validation实例。

例子:同时处理多个Validation

假设我们需要同时验证几个值,并返回所有异常信息,可以使用Validation的组合操作符|@|

((3.success : Validation[String, Int]) |@| ("oh, error1! ".failure : Validation[String, Int]) |@| (2.success : Validation[String, Int]) |@| ("oh, error2 again!".failure : Validation[String, Int])) {_ + _ + _ + _}

上述代码将返回一个Failure,携带所有异常信息。例如:

Failure("oh, error1! oh, error2 again!")

如果需要将异常信息存储在NonEmptyList中,可以使用failureNel方法:

((3.successNel : ValidationNel[String, Int]) |@| ("oh, error1! ".failureNel : ValidationNel[String, Int]) |@| (2.successNel : ValidationNel[String, Int]) |@| ("oh, error2 again!".failureNel : ValidationNel[String, Int])) {_ + _ + _ + _}

上述代码将返回一个Failure,携带所有异常信息:

Failure(NonEmptyList("oh, error1!", "oh, error2 again!"))

NonEmptyList的使用

NonEmptyList是Scalaz中用于表示不为空列表的数据结构。它可以与Validation结合使用,方便地将异常信息存储和处理。

例如:

val nel = 2 :@: 4 :@: 3.wrapNel

上述代码将返回一个NonEmptyList,包含元素2、4和3。

如果需要将其转换为标准的List,可以使用list方法:

nel.list

这将返回一个标准的List[2, 4, 3]。

Validation的flatMap方法

尽管Validation支持flatMap方法,但它已经被弃用。用户被鼓励使用Scalaz的标准库/或直接使用Validation的其他方法。例如,可以使用ap方法来处理多个Validation。

deprecated警告

@deprecated("flatMap does not accumulate errors, use `scalaz.\/` or `import scalaz.Validation.FlatMap._` instead", "7.1")
@inline implicit def ValidationFlatMapDeprecated[E, A](d: Validation[E, A]): ValidationFlatMap[E, A] = new ValidationFlatMap(d)

用户被建议使用Scalaz的标准库/来处理错误积累问题。

Validation的Applicative特性

Validation实现了Applicative功能,通过ap方法可以在成功路径上应用函数,并处理失败路径上的异常。例如:

def ap[EE: Semigroup[EE], B](x: => Validation[EE, A => B])(implicit E: Semigroup[EE]): Validation[EE, B] = (this, x) match {
case (Success(a), Success(f)) => Success(f(a))
case (e @ Failure(_), Success(_)) => e
case (Success(_), e @ Failure(_)) => e
case (Failure(e1), Failure(e2)) => Failure(E.append(e2, e1))
}

上述方法允许开发者在Validation的成功路径上应用函数,并将多个异常信息合并到一个Failure中。

总结

Validation是Scalaz中处理数据验证和错误处理的强大工具。它通过其Applicative特性,支持同时处理多个Validation,并返回多个异常信息。与/相比,Validation的主要优势在于其更灵活的错误处理能力。通过合理使用Validation及其注入方法,开发者可以构建更高效、更健壮的错误处理逻辑。

转载地址:http://wfefz.baihongyu.com/

你可能感兴趣的文章
mongodb定时备份数据库
查看>>
mppt算法详解-ChatGPT4o作答
查看>>
mpvue的使用(一)必要的开发环境
查看>>
MQ 重复消费如何解决?
查看>>
mqtt broker服务端
查看>>
MQTT 保留消息
查看>>
MQTT 持久会话与 Clean Session 详解
查看>>
MQTT工作笔记0007---剩余长度
查看>>
MQTT工作笔记0009---订阅主题和订阅确认
查看>>
Mqtt搭建代理服务器进行通信-浅析
查看>>
MS Edge浏览器“STATUS_INVALID_IMAGE_HASH“兼容性问题
查看>>
ms sql server 2008 sp2更新异常
查看>>
MS UC 2013-0-Prepare Tool
查看>>
MSBuild 教程(2)
查看>>
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>
MSCRM调用外部JS文件
查看>>
MSCRM调用外部JS文件
查看>>
MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
查看>>
MsEdgeTTS开源项目使用教程
查看>>