gpt4 book ai didi

scala - 理解 Scala 中的 IO monad

转载 作者:行者123 更新时间:2023-12-04 15:39:51 25 4
gpt4 key购买 nike

我正在学习 scalaz,现在我正在尝试理解 IO 的要点单子(monad)。我读了this article关于 IO monads 并尝试自己运行最简单的示例:

val io = println("test").pure[IO]
println("before")
io.unsafePerformIO()

是的,它按预期工作。它打印
before
test

但我无法理解 IO 单子(monad)的要点。诀窍是什么?除了我引用的文章中指定的“保持替换”。

现在,这种替代对我来说似乎不太有用。你能解释一下吗?

从我能想到的。想象一下我有一些特点:
trait Reader{
def read(): List[Int]
}

trait Writer[T]{
def write(t: T): Unit
}

所以我有一个可以读取一元值的阅读器(在我的例子中是 List)。然后我需要将容器中的所有值写入其他地方,对它们执行一些转换。 IO monad 在这种情况下有用吗?

最佳答案

IO 就在我们身边,它使程序真正有用,因为我们不能整天只计算纯表达式。

IO monad 试图解决使 IO 操作“不纯”的问题,例如从不纯的来源(例如网络)获取数据。

IO,就其本身而言,不是引用透明的。考虑一个返回 Unit 的方法,如 println例如。让我们尝试替换println只需 Unit (或 () ),我们不会得到相同的值,不是吗?因为println具有打印到控制台的效果。

使用您的示例,想象一下:

def write(t: T): Unit

如果我们替换 write 会发生什么与 () ?好吧,写入外部源会产生影响。但是,如果我们使用 IO[Unit] ,我们不会破坏替代。

要真正查看您的问题,我们需要结合 List带有 IO 的单子(monad)monad,正如我们所知,monad 不会组合。我们需要使用 Monad Transformers 的一些技巧:
import cats._
import cats.data.Nested
import cats.effect.IO
import cats.implicits._

val nested = Nested(IO.pure(reader.read()))
val res: Nested[IO, List, IO[Unit]] =
Functor[Nested[IO, List, ?]].map(nested)(i => writer.write(i))

val ioResult = for {
listOfIO <- res.value
flattened <- Applicative[IO].sequence(listOfIO)
} yield flattened

ioResult.unsafeRunSync()

这不是很漂亮,而且可能不像调用返回 Unit 的有效操作那么简单。 ,但我确信有比我在这里为演示目的创建的更好的方法来解决 monad 组合。

关于scala - 理解 Scala 中的 IO monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47414606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com