scala - Monads 是一种用于排序计算的机制,下面的列表是否仍然是一个 monad,尽管它们是以随机顺序打印的 Scala
问题描述
for {
i <- 1 to 5
} yield Future(println(i))
转为:
List(1,2,3,4,5).map {i => Future(println(i))}
上面的代码以随机顺序打印数字。
现在,如果我们看到 Monad 的多个定义: a) Monad 是对象的包装器 b) Monad 是一种用于排序计算的机制
我要回答的问题是,List monad 上的映射操作不应该等待列表中的第一个元素被打印出来,然后才去计算第二个元素,而不管未来如何?
对不起,这可能很简单,我把它复杂化了,但我很难找到简单的推理。答案将不胜感激:)
解决方案
相比:
for {
_ <- Future(println(1))
_ <- Future(println(2))
_ <- Future(println(3))
_ <- Future(println(4))
_ <- Future(println(5))
} yield ()
或者
Future(println(1)).flatMap { _ =>
Future(println(2))
}.flatMap { _ =>
Future(println(3))
}.flatMap { _ =>
Future(println(4))
}.flatMap { _ =>
Future(println(5))
}
和
List(
Future(println(1)),
Future(println(2)),
Future(println(3)),
Future(println(4)),
Future(println(5))
)
Future
只有在前者完成并提供结果后,前两个才会创建下一个。最后一个同时创建所有Future
s (在这方面它与您的示例没有太大区别List[Future]
)。
Future
(与IO
Cats Effect、Monix'sTask
或 ZIO 不同)是渴望的,因此它会在您创建它的那一刻开始执行。出于这个原因,前两个示例中有顺序结果,第三个示例中有随机顺序(竞争条件)。
如果你使用它IO
而不是Future
它会更明显,因为你不能仅仅拥有List[IO[Unit]]
和执行副作用 - 你必须以某种方式将不同的 IO 组合成一个,并且你这样做的方式会很明显是否效果将是顺序的或并行的。
底线是 - 是否Future
是 monad 取决于它的.flatMap
行为方式(以及它与 组合的行为方式Future.successful
),因此您的结果不会使Future
作为 monad 的声明无效。(如果您开始检查它的异常行为,您可能会有一些疑问,但这是另一个话题)。
推荐阅读
- php - 将“WooCommerce”仪表板菜单选项名称更改为“商店”
- ios - Nativescript 检测方向而不自动旋转屏幕内容
- python - python中的字符串连接使用不同的方法占用指数内存
- c# - 多个带有代理的 HttpClients,试图达到最大的下载速度
- design-patterns - 用于重用具有略微不同逻辑的公共代码的设计模式
- javascript - 如何在数组中相应地选择字段的值的总数
- python - skimage.transform.rescale 为输入图像添加了一个额外的维度
- python - 在使用两种不同方法创建的二维列表中分配值时出现问题
- sql - oracle中从另一张表中减去一张表的一列的值的SQL语句是什么
- javascript - 如何在平面列表中打印图像组件?反应原生