我对函数式编程和Scala还不熟悉,最近查看了Cats Effect框架并试图了解IO单子的作用。目前我的理解是,在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)
}
输出结果如下:
13
paused
我不明白为什么赋值语句 state = newState
不执行,但增加和赋值表达式 out += 1
执行。我是否错过了一些关于如何工作的明显内容?我真的需要帮助。我知道可以使用 unsafe
方法来运行此代码。
var
在你的代码中就没有位置了。IO Monad
的整个重点在于包含副作用。如果你想要维护这样的可变状态,cats
会为你提供许多选项,例如Ref
。 - sinanspd