快速功能链接失败

时间:2015-02-10 17:53:08

标签: scala

想知道是否有更好的技术来实现Any上的函数链接,如果遇到APIException对象将停止链(不必扩展Throwable或{ {1}},或使用Exception)。此外,我宁愿不使用throw(让我头晕)

  1. 链接功能应该scalaz一直到最后并返回。
  2. 除了最后一个块的输出外,链接功能不必将中间结果带到最后。
  3. 这是一个测试规范:

    APIException

    这是我提出的一个实现,寻找对此的改进。

    class FailFastChainSpec extends PlaySpec {
    
      import utils.Ops._
    
      def fFailsValidation(): Option[APIException] = Some(UnknownException())
    
      def fPassesValidation(): Option[APIException] = None
    
      def someCalculation = "Results"
    
      "Utils" when {
    
        "FailFastChaining" must {
          "return Left(APIException) when encountered (at beginning of chain)" in {
            fFailsValidation |> {
              someCalculation
            } mustBe Left(UnknownException())
          }
    
          "return Right(...) when no APIExceptions are encountered" in {
            fPassesValidation |> {
              someCalculation
            } mustBe Right(someCalculation)
          }
    
          "return Left(APIException) when encountered (in middle of chain with 1 link)" in {
            fPassesValidation |> fFailsValidation mustBe Left(UnknownException())
          }
    
          "return Left(APIException) when encountered (at end of chain with 1 link)" in {
            fPassesValidation |> {
              Left(UnknownException())
            } mustBe Left(UnknownException())
          }
    
          "return Left(APIException) when encountered (at end of chain with 2 links)" in {
            fPassesValidation |> fPassesValidation |> {
              Left(UnknownException())
            } mustBe Left(UnknownException())
          }
    
          "return Right(...) when no APIExceptions are encountered (multiple links)" in {
            fPassesValidation |> fPassesValidation |> fPassesValidation |> fPassesValidation |> {
              Right(someCalculation)
            } mustBe Right(someCalculation)
          }
    
          "return Right(...) when no APIExceptions are encountered (complex multiple links)" in {
            fPassesValidation |> fPassesValidation |> {
              Right("Cupcakes")
            } |> fPassesValidation |> {
              Right(someCalculation)
            } mustBe Right(someCalculation)
          }
    
        }
    
      }
    }
    

1 个答案:

答案 0 :(得分:0)

如果将Option类型与for comprehension结合使用,则可以模拟monadic行为:

  import scala.util.control.Exception._
  import scala.util._

  def dangerousOp = throw new RuntimeException("never works")

  def f1(s: Int): Try[Int] = Success(s * 10)
  def f2(s: Int): Try[Int] = catching(classOf[Exception]) toTry dangerousOp
  def f3(s: Int): Try[Int] = Success(s * 30)

  val result = for {
    x <- f1(10)
    y <- f2(x)
    z <- f3(y)
  } yield z

  println(result) // Failure(java.lang.RuntimeException: never works)

如果其中任何一个失败并且没有,则无将传播到收益。

编辑:示例方法f2现在抛出异常以显示如何将它们集成到此链中。也改为尝试使其更像你的例子。