在scala def convert(f:()⇒Future [Int]):Future [()⇒Int] =中可能吗?

时间:2018-08-06 15:55:48

标签: scala functional-programming future

convert

是否可以使用上面的签名来实现convert(computeComplexNumber)方法,条件是在调用Await.result(convert(computeComplexNumber), 5.seconds)() 时,除非执行此操作,否则什么都不会打印出来

g <- erdos.renyi.game(10,.3)

g <- set_vertex_attr(g,"a", index = V(g), 1)
g <- set_vertex_attr(g,"b", index = V(g), 1)
g <- set_vertex_attr(g,"c", index = V(g), 1)
g

l<- c("a", "b", "c")
for (i in l){
  g2<-delete_vertex_attr(g, i)
}
g2

3 个答案:

答案 0 :(得分:10)

如果没有在convert内部进行封锁,我看不到有任何办法。如果不调用Future[X],根本无法在convert内部获得f的实例。但是一旦调用fFuture { ... }就会急切地开始使用println来评估该块,并产生输出。

您可能想看看scalaz.concurrent.Task

答案 1 :(得分:2)

如果要将() => Future[Int]转换为() => Int,则必须等待Future的结果,如下所示:

def convert(f: () ⇒ Future[Int]): Future[() ⇒ Int] =
  Future{
    () => Await.result(f(), Duration.Inf)
  }

然后

val f = convert(computeComplexNumber) // Get Future
val g = Await.result(f, Duration.Inf) // Get Function
g() // Call function

在您致电g之前,不会显示输出。


回应评论的解释

问题

这个问题的核心是这个函数签名:

def convert(f: () ⇒ Future[Int]): Future[() ⇒ Int]

(在释义中)还有一个要求

  

f在调用返回的函数之前不会被调用

此外,我假设结果中的Int是参数中Future返回的值,而不仅仅是一些随机数!

问题

输入函数的返回类型为Future[Int],输出函数的返回类型为Int。第一个是异步结果,第二个是同步结果。因此,任何解决方案都必须从异步Future[Int]转换为同步Int。这意味着Await.result或类似名称。

还要求在执行输出功能之前不执行输入功能。这意味着必须在返回的函数内部调用它 ,这又意味着必须在返回的函数内部调用Await.result

解决方案

上述解决方案具有问题所需的convert功能签名。在执行f返回的函数之前,它也不会调用convert,这是另一个要求。

convert的实现没有阻塞;它立即返回一个Future值。它不调用f,而只是返回一个函数。

评论

在一个函数内部阻塞或一个函数调用另一个函数的含义存在争议。阻塞和调用是函数执行期间发生的过程。因此,对这些在“函数内部”发生的事物的明智定义是,它们发生在函数入口点的执行与函数出口点的执行之间。使用此定义,很明显解决方案不会在函数内部阻塞或在函数内部调用f

提问者还评论说Await.result不应在任何地方被调用。不幸的是,如上所述,这是不可能的,因为要求是将异步结果转换为同步结果。

答案 2 :(得分:-1)

也许这样可以工作:

 def computeComplexNumber: () => Future[Int] = () =>
  Future {
    delay(4.seconds.fromNow)
    println("Computing complex number ...")
    Int.MaxValue
  }

  def convert(f: () => Future[Int]): Future[() => Int] = {
    f().map( m => () => m)
  }

  def delay(dur:Deadline) = {
    Try(Await.ready(Promise().future, dur.timeLeft))
  }
相关问题