如何在Scala中使用for而不是flatMap / map?

时间:2016-05-26 09:29:16

标签: scala scala-cats

我在堆栈中了解Scala for是如何工作的。 我认为以下代码可以用for编写,但我不知道怎么做。 有人可以解释我怎么做吗?

def foo: Future[Option[Int]] = ???
def bar: Future[Throwable Xor Option[Int]] = ???
def baz: Future[Option[Boolean]] = ???

foo.flatMap {
  case Some(x) =>
    Future.successful(x)
  case None =>
    bar.flatMap {
      case Xor.Right(Some(x)) =>
        baz.map {
          case true => 1
          case false => 0
        }
      case Xor.Right(None) =>
        Future.successful(0)
      case Xor.Left(_) =>
        Future.successful(-1)
    }
}

2 个答案:

答案 0 :(得分:4)

由于flatMap函数中的所有分支,因此无法将其写为理解。

可以用fold方法替换模式匹配,但这可能是个人偏好的问题。

Option("suish") match {
  case Some(name) => s"hello $name"
  case None => "hello world"
}
// is analogous to
Option("suish").fold("hello world")(name => s"hello $name")

我使用OptionTtutorial),XorTfold的{​​{1}}方法重写了您的模式匹配,但我不确定如果这比嵌套模式匹配更具可读性。

Option

答案 1 :(得分:3)

在for-comprehensions中无法模式匹配。见Allow pattern matching on type in for comprehensions

也许您可以使用Monad Transformers。我确实希望以这种方式实现您的代码,但我现在没有时间。也许提示可以帮助你。

/编辑这不完全正确,正如谢尔盖的评论所指出的那样。只要所有匹配类型相同,您就可以在for-comprehension中进行模式匹配。查看此图片来自second lesson of the first week of Functional Program Design in Scala Coursera Course,其中所有模式均来自JSON

For-comprehension and pattern matching