加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

了解Scala中的IO monad

发布时间:2020-12-16 18:34:54 所属栏目:安全 来源:网络整理
导读:我正在学习 scalaz,现在我正在努力理解IO monad的观点.我阅读了有关IO monads的 this article 并尝试自己运行最简单的示例: val io = println("test").pure[IO]println("before")io.unsafePerformIO() 是的,它按预期工作.它打印 beforetest 但我无法抓住IO
我正在学习 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组合,而不是我为了演示而创建的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读