Rav*_*she 1 monads scala future sequential for-comprehension
for {
i <- 1 to 5
} yield Future(println(i))
Run Code Online (Sandbox Code Playgroud)
脱糖:
List(1,2,3,4,5).map {i => Future(println(i))}
Run Code Online (Sandbox Code Playgroud)
上面的代码以随机顺序打印数字。
现在,如果我们看到 Monad 的多个定义: a) Monad 是一个对象的包装器 b) Monad 是一种排序计算的机制
我试图回答的问题是,不应该在 List monad 上映射操作等待列表中的第一个元素被打印出来,然后才去计算第二个元素而不管 Future 是什么?
抱歉,这可能很简单,而且我把它复杂化了,但我很难找到简单的推理。答案将不胜感激:)
相比:
for {
_ <- Future(println(1))
_ <- Future(println(2))
_ <- Future(println(3))
_ <- Future(println(4))
_ <- Future(println(5))
} yield ()
Run Code Online (Sandbox Code Playgroud)
或者
Future(println(1)).flatMap { _ =>
Future(println(2))
}.flatMap { _ =>
Future(println(3))
}.flatMap { _ =>
Future(println(4))
}.flatMap { _ =>
Future(println(5))
}
Run Code Online (Sandbox Code Playgroud)
和
List(
Future(println(1)),
Future(println(2)),
Future(println(3)),
Future(println(4)),
Future(println(5))
)
Run Code Online (Sandbox Code Playgroud)
Future只有在前者完成并使结果可用后,前两个才会创建下一个。最后一个同时创建所有Futures(在这方面与您的示例没有太大区别List[Future])。
Future(IO与 Cats Effect、Monix'sTask或 ZIO 不同)是急切的,因此它在您创建它的那一刻就开始执行。出于这个原因,您在前两个示例中具有顺序结果,在第三个示例中具有随机顺序(竞争条件)。
如果你使用IO而不是Future它会更明显,因为你不能只拥有List[IO[Unit]]和执行副作用 - 你必须以某种方式将不同的 IO 组合成一个,并且你这样做的方式会很明显效果将是顺序的或并行的。
底线是 - 是否Future是 monad 取决于它的.flatMap行为方式(以及它与 组合的行为方式Future.successful),因此您的结果不会使Future作为 monad的声明无效。(如果您开始检查其异常行为,您可能会有一些疑问,但这是另一个主题)。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |