设为首页 加入收藏

TOP

Scalaz(20)-Monad: Validation-Applicative版本的Either(一)
2017-10-10 12:13:26 】 浏览:5317
Tags:Scalaz Monad Validation Applicative 版本 Either

  scalaz还提供了个type class叫Validation。乍看起来跟\/没什么分别。实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数。通过Applicative实例就可以同时运算多个Validation并返回多条异常信息。所以,\/与Validation核心分别就在于Validation可以返回多条异常信息。Validation也是由两种状态组成:Success和Failure,分别与\/的left和right相对应。Failure可以返回多个值。我们先来看看Validation在scalaz里的定义:scalaz/Validation.scala

sealed abstract class Validation[+E, +A] extends Product with Serializable { ... def isSuccess: Boolean = this match { case Success(_) => true
    case Failure(_) => false } /** Return `true` if this validation is failure. */ def isFailure: Boolean = !isSuccess ... /** Return the success value of this validation or the given default if failure. Alias for `|` */ def getOrElse[AA >: A](x: => AA): AA =
    this match { case Failure(_) => x case Success(a) => a } /** Return the success value of this validation or the given default if failure. Alias for `getOrElse` */ def |[AA >: A](x: => AA): AA = getOrElse(x) /** Return the success value of this validation or run the given function on the failure. */ def valueOr[AA >: A](x: E => AA): AA =
    this match { case Failure(a) => x(a) case Success(b) => b } /** Return this if it is a success, otherwise, return the given value. Alias for `|||` */ def orElse[EE >: E, AA >: A](x: => Validation[EE, AA]): Validation[EE, AA] =
    this match { case Failure(_) => x case Success(_) => this } /** Return this if it is a success, otherwise, return the given value. Alias for `orElse` */ def |||[EE >: E, AA >: A](x: => Validation[EE, AA]): Validation[EE, AA] = orElse(x) ...

与\/非常相似,也是提供了getOrElse来获取Success[A]的A值。如果需要获取Failure[B]值则与\/一样先用swap再用getOrElse:

/** Flip the failure/success values in this validation. Alias for `unary_~` */ def swap: Validation[A, E] =
    this match { case Failure(a) => Success(a) case Success(b) => Failure(b) } Success(3).getOrElse(0)                           //> res5: Int = 3
Success("Three").getOrElse("Everything OK!")      //> res6: String = Three
Failure("Something wrong!").swap.getOrElse("Everything OK!") //> res7: String = Something wrong!
(~Failure("Something wrong!")).getOrElse("Everything OK!") //> res8: String = Something wrong!

 Validation的两个状态是这样定义的:

final case class Success[A](a: A) extends Validation[Nothing, A] final case class Failure[E](e: E) extends Validation[E, Nothing]

Validation也是一个Monad,可以在for-comprehension中实现Failure立即退出功能:

 1 for {  2   a <- Success(3)  3   b <- Success(2)  4 } yield a + b                                     //> res5: scalaz.Validation[Nothing,Int] = Success(5)
 5 
 6 val valid= for {  7   a <- Success(3)  8   c <- Failure("oh, error!"): Validation[String,Int]  9   d <- Failure("oh, error again!"): Validation[String,Int] 10   b <- Success(2) 11 } yield a + b                                     //> valid : scalaz.Validation[String,Int] = Failure(oh, error!)
12 if (valid.isFailure) valid.swap.getOrElse("no error") 13                                                   //> res6: Any = oh, error!

scalaz同样为所有类型值提供了注入方法:scalaz.syntax/ValidationOps.scala

final class ValidationOps[A](self: A) { def success[X]: Validation[X, A] = Validation.success[X, A](self) def successNel[X]: ValidationNel[X, A] = success def failure[X]: Validation[A, X] = Validation.failure[A, X](self) @deprecated("use `failure` instead", "7.1") def fail[X]: Validation[A, X] = failure[X] def failureNel[X]: ValidationNel[A, X
编程开发网
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scalaz(19)- Monad: \/ - Mon.. 下一篇Scalaz(21)-类型例证:Liskov ..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }