scala - IO monad 如何使 Scala 中的并发变得容易?

标签 scala concurrency io-monad

我看这个video从6分35秒开始,它提到了这个图表:

enter image description here

据说 IO Monad 可以轻松处理并发。我对此感到困惑:它是如何工作的?两个for commination如何实现并发(df的计算)?

最佳答案

不,它不会启用并发

for 推导式只能帮助您省略几个括号和缩进。

您引用的代码,翻译为[flat]map严格等同于:

async.boundedQueue[Stuff](100).flatMap{ a => 
  val d = computeB(a).flatMap{
    b => computeD(b).map{ result =>
      result
    }
  }

  val f = computeC(a).flatMap{ c =>
    computeE(c).flatMap{ e =>
      computeF(e).map{ result =>
        result
      }
    }
  }

  d.merge(f).map(g => g)
}

看,它只能帮助你省略几个括号和缩进(笑话)

并发隐藏在flatMapmap

一旦您了解了 for 如何转换为 flatMapmap 后,您就可以在它们内部实现并发。

由于 map 以函数作为参数,这并不意味着该函数在 map 函数执行期间执行,您可以将该函数推迟到另一个线程或稍后运行它。这就是并发的实现方式。

PromiseFuture为例:

val future: Future = ```some promise```
val r: Future = for (v <- future) yield doSomething(v)
// or
val r: Future = future.map(v => doSomething(v))
r.wait

函数doSomethingFuture.map函数执行期间不会被执行,而是在promise提交时被调用。

结论

如何使用for语法suger实现并发:

  1. for 会被 scala 编译器转换成 flatMapmap
  2. 编写 flatMapmap,您将从参数中获取回调函数
  3. 随时随地调用您所拥有的功能

进一步阅读

许多语言的流程控制功能共享相同的属性,它们就像分隔延续shift/reset,它们将以下执行捕获到函数的范围内。

JavaScript:

async function() {
  ...
  val yielded = await new Promise((resolve) => shift(resolve))
                                  // resolve will captured execution of following statements upto end of the function.
  ...captured
}

haskell :

do {
  ...
  yielded_monad <- ```some monad``` -- shift function is >>= of the monad
  ...captured
}

斯卡拉:

for {
  ...
  yielded_monad <- ```some monad``` // shift function is flatMap/map of the monad
  ...captured
} yield ...

下次当您看到将后续执行捕获到函数中的语言功能时,您就知道可以使用该功能实现流程控制。

定界延续和 call/cc 之间的区别在于,call/cc 捕获程序的整个后续执行,但定界延续有一个范围。

关于scala - IO monad 如何使 Scala 中的并发变得容易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54087320/

相关文章:

haskell - 为什么我不能调用函数快速排序 (randomList 10)?

Scala split 于\n

java - 如何从提交给执行者的已取消+中断的可调用项中获取异常?

scala - 为什么在 Scala 中不能用 `var` 覆盖 `def`?

c - 如何为 TMS320F2812 DSP 编写内存屏障?

scala - 为什么使用复制比串行执行慢得多?

haskell - 这种类型的签名发生了什么? (Haskell 中的 Vector.Mutable 修饰符)

Scala Cats效果-IO异步移位-如何工作?

scala - 使用 self 类型扩展 trait 时非法继承

regex - 模式匹配时是否可以使非捕获组在 Scala 正则表达式中工作