了解Scala中的IO monad
我正在学习
scalaz,现在我正在努力理解IO monad的观点.我阅读了有关IO monads的
this article并尝试自己运行最简单的示例:
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 } 所以我有一个读取器可以读取monadic值(在我的情况下为List).然后我需要在其他地方的容器中写入所有值,对它们执行一些转换. IO monad在这种情况下有用吗? 解决方法
IO就在我们身边,它使程序真正有用,因为我们不能整天计算纯表达式.
IO monad试图解决使IO操作“无法”的问题,例如从不纯的源(例如网络)获取数据. IO,就其本身而言,不是指称透明的.想想一个返回Unit的方法,比如println.让我们尝试将println替换为Unit(或()),我们不会得到相同的值,是吗?因为println具有打印到控制台的效果. 使用您的示例,想象: def write(t: T): Unit 如果我们用()代替写,会发生什么?那么,写入外部源会产生影响.但是,如果我们使用IO [Unit],我们就不会打破替换. 要实际查看你的问题,我们需要将List monad与IO monad结合起来,而且我们知道monad不会编写.我们需要借助Monad变形金刚的一些技巧: 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,?]].map(nested)(i => writer.write(i)) val ioResult = for { listOfIO <- res.value flattened <- Applicative[IO].sequence(listOfIO) } yield flattened ioResult.unsafeRunSync() 这不是很漂亮,并且可能不像调用返回Unit的有效操作那么直接,但我确信有更好的方法来解决monad组合,而不是我为了演示而创建的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |