scala - 如何使用 Scalaz 或 Cats 重构抛出异常的函数

标签 scala refactoring scalaz scala-cats

这是我之前的 question 的后续内容:

假设我正在重构这样的函数:

def check(ox: Option[Int]): Unit = ox match {
  case None => throw new Exception("X is missing")
  case Some(x) if x < 0 => throw new Exception("X is negative")
  case _ => ()
}

我正在编写一个新的纯函数doCheck来返回Unit或异常。

case class MissingX() extends Exception("X is missing")
case class NegativeX(x: Int) extends Exception(s"$x is negative")

import scalaz._, Scalaz._

type Result[A] = Excepiton \/ A

def doCheck(ox:Option[Int]): Result[Unit] = for {
  x <- ox toRightDisjunction MissingX()
  _ <- (x >= 0) either(()) or NegativeX(x)
} yield ()

然后从check调用它

def check(ox:Option[Int]): Unit = doCheck(ox) match {
  case -\/(e) => throw e
  case _ => ()
}

这有道理吗?像这样实现 doCheck 会更好吗?

def doCheck(ox:Option[Int]): Result[Int] = for {
  x1 <- ox toRightDisjunction MissingX()
  x2 <- (x1 >= 0) either(x1) or NegativeX(x1)
} yield x2

如何用cats实现它?

最佳答案

你会在猫身上做几乎相同的事情,只有猫本身没有 Boolean => Xor[A, B] 语法,如 () 或 ()来自 Scalaz 。

import cats.data.Xor
import cats.implicits._

def doCheck(ox: Option[Int]): Xor[Exception, Unit] =
  ox.toRightXor(MissingX()).flatMap(x => if(x > 0) ().right else NegativeX(x).left)

您可以使用mouse ,它为猫提供了类似的语法帮助器:

import com.github.benhutchison.mouse.boolean._

ox.toRightXor(MissingX()).flatMap(x => (x > 0).toXor(NegativeX(x), ()))

Xor 也有方法 ensure 来执行类似的操作,但如果谓词不成立,它不会让您访问该元素。如果您不需要 NegativeXx,您可以编写:

ox.toRightXOr(MissingX()).ensure(Negative())(_ > 0).void

关于scala - 如何使用 Scalaz 或 Cats 重构抛出异常的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37915718/

相关文章:

validation - 将验证与 scalaz 7 相结合

scala - 无法在 Scala 中编写同时适用于 Double 和 Float 的方法

delphi - 如何检测接口(interface)和实现uses子句中无用的Delphi单元?

scala - 过滤 scalaz 析取右侧的值

java - 将读取两个文件的两种方法合并为用一种方法读取一个文件

java - 在 Eclipse 中内联所有静态导入

scala - 将 scalaz 析取集合转换为单个析取

scala - 在 Scala 中,隐式使用参数,但不要隐式传递它

scala - 如何在集合上减少(),将集合本身​​保留在 Scala 中?

scala - 注入(inject)数据库依赖 scala 对象