在Semigroupal的一些单子中,我们是否仍然失去了背景?

问题描述 投票:0回答:1

我正在读“Scala with cats”一书。作者说,Semigroupal并不总能提供我们期望的行为。他展示了这个例子:

import cats.Semigroupal
import cats.instances.future._ // for Semigroupal
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.language.higherKinds
val futurePair = Semigroupal[Future].
product(Future("Hello"), Future(123))
Await.result(futurePair, 1.second)
// res1: (String, Int) = (Hello,123)

在书中结果是(Hello,123)但我们期待Future(Hello, 123)。据我所知,我们失去了Future,所以没有预期的背景。

我决定重现这个例子并得到这个结果:

Future(Success((Hello,123)))

在这里的背景。嗯。然后我尝试了这个实验:

  val futurePair = Semigroupal[Future]
    .product(Future{Thread.sleep(100);"Hello"}, Future(123))
  println(futurePair)

结果是Future(<not completed>)。正如我所料。

所以我无法理解Future有什么问题。我得到了预期的行为,我没有失去计算的背景。也许是因为Future在创建的那一刻开始计算?但为什么这是一个问题呢?

scala functional-programming scala-cats
1个回答
0
投票

Await.result剥离了Future,而不是product,所以你的期望与这里的实际行为相匹配。他所说的是有些人可能期望顺序执行而不是并行,因为其他半群的表现如何,但他选择了一个糟糕的代码示例,因为他的例子的结果是相同的,无论是并行执行还是顺序执行。一个更好的例子来说明作者的观点是这样的:

val futurePair = Semigroupal[Future].product(
  Future{Thread.sleep(750); "Hello},
  Future{Thread.sleep(750); 123}
)
Await.result(futurePair, 1.second)

如果Await.result按顺序运行,Futures会超时。

© www.soinside.com 2019 - 2024. All rights reserved.