我们是否仍然会丢失一些带有半群的单子的上下文



我正在读《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创建时开始计算?但为什么这是一个问题?

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

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

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

相关内容

  • 没有找到相关文章

最新更新