scala - 如果使用 cats IO 选项为 None,如何停止 for-compression 的执行?

标签 scala functional-programming monads scala-cats

如果我只是在理解中使用 Option ,一切都会按预期进行:

val a = Some(1)
val b = None
val c = Some(3)

val r = for {
  aa <- a
  bb <- b
  cc <- c
} yield aa + bb + cc

println(r) // None, because b is None

但是如何使用cats IO 实现相同的行为呢?

import cats.effect.IO
// in reality this will be a methods with side effect
val a = Some(1)
val b = None
val c = Some(3)

val r = for {
  _ <- IO{println("a"); a}
  _ <- IO{println("b"); b} // want to stop execution here
  _ <- IO{println("c"); c}
} yield ()

r.unsafeRunSync()

结果我得到a b c,但我期望只有a b

可以实现吗?这是正确的做法吗?

最佳答案

你可以使用 monad 转换器来做到这一点;具体来说,您需要使用 OptionT[IO, T]这里:

import cats.effect._
import cats.data.OptionT
import cats.implicits._
import cats.effect.IO

val a = Some(1)
val b = None
val c = Some(3)

val r = for {
  _ <- OptionT[IO, Int](IO {println("a"); a})
  _ <- OptionT[IO, Int](IO {println("b"); b})
  _ <- OptionT[IO, Int](IO {println("c"); c})
} yield ()

r.value.unsafeRunSync() 

查看实际效果 here .

关于scala - 如果使用 cats IO 选项为 None,如何停止 for-compression 的执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53393458/

相关文章:

json - 使用 Scala/Play 将 JSON 转换为带有嵌套对象的 case 类

scala - 更改 sbt 的输出目录

json - 如何使用 json4s 从 akka-http 响应实体读取 json 响应

Javascript 作为函数式语言

rust - 如何将 Vec<Result<T, E>> 转换为 Result<Vec<T>, E>?

scala - 如何比较两个数据集?

types - 派生类型的模式匹配对于 F# 来说是惯用的吗?

javascript - 如何选择javascript数组中的最后N个成员(函数式)

haskell - `mfix` 未按预期工作

scala - 是否有任何理由制作 Future[Try[A]] 类型的 API 而不是 Future[A]?