如何使用 Scalaz 或 Cats 重构抛出异常的函数
How to refactor a function that throws exceptions with Scalaz or Cats
这是我之前 :
的后续
假设我正在重构这样一个函数:
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
到 return 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
实现?
你会在猫身上做同样的事情,只是猫本身没有像 scalaz 的 either () or ()
那样的 Boolean => Xor[A, B]
语法。
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
来做这样的事情,但如果谓词不成立,它不会让您访问元素。如果 NegativeX
不需要 x
,你可以这样写:
ox.toRightXOr(MissingX()).ensure(Negative())(_ > 0).void
这是我之前
假设我正在重构这样一个函数:
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
到 return 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
实现?
你会在猫身上做同样的事情,只是猫本身没有像 scalaz 的 either () or ()
那样的 Boolean => Xor[A, B]
语法。
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
来做这样的事情,但如果谓词不成立,它不会让您访问元素。如果 NegativeX
不需要 x
,你可以这样写:
ox.toRightXOr(MissingX()).ensure(Negative())(_ > 0).void