繁体   English   中英

猫效应 IO 单子如何真正起作用?

[英]How does the cats-effect IO monad really work?

我是函数式编程和 Scala 的新手,我正在检查 Cats Effect 框架并试图了解 IO monad 的作用。 到目前为止,我所理解的是,在 IO 块中编写代码只是对需要做的事情的描述,在您使用提供的unsafe方法显式运行之前什么都不会发生,也是一种制作执行副作用的代码的方法通过实际不运行它来实现引用透明。

我尝试执行下面的代码片段只是为了理解它的含义:

object Playground extends App {
  var out = 10
  var state = "paused"

  def changeState(newState: String): IO[Unit] = {
    state = newState
    IO(println("Updated state."))
  }

  def x(string: String): IO[Unit] = {
    out += 1
    IO(println(string))
  }

  val tuple1 = (x("one"), x("two"))

  for {
    _ <- x("1")
    _ <- changeState("playing")
  } yield ()

  println(out)
  println(state)
}

output 是:

13
paused

我不明白为什么赋值state = newState没有运行,但是增量和赋值表达式out += 1运行。 我是否遗漏了一些关于这应该如何工作的明显内容? 我真的可以使用一些帮助。 我知道我可以使用unsafe的方法来运行它。

在您的特定示例中,我认为正在发生的事情是常规的命令式 Scala 编码不受IO monad 的影响 - 它在 Scala 的规则下正常运行。

当你运行时:

for {
  _ <- x("1")
  _ <- changeState("playing")
} yield ()

这立即调用x 这与IO monad 无关; 这就是定义理解for方式。 第一步是评估第一个语句,以便您可以在其上调用flatMap

正如您所观察到的,您从不“运行”一元结果,因此从不调用flatMap的参数(一元延续),从而不会调用changeState 这是特定于IO monad,例如, List monad 的flatMap会立即调用 function(除非它是一个空列表)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM