【问题标题】:Tail-recursion and scalaz promises尾递归和 scalaz 承诺
【发布时间】:2011-08-21 16:30:09
【问题描述】:

我目前正在玩 Scalaz 非阻塞期货。承诺。我正在努力使以下函数尾递归:

@tailrec
private def repeat( res: Promise[I] ):Promise[I] =
  res map p flatMap { 
    (b:Boolean) =>
      if( b ) repeat( res flatMap f ) else res
  }

其中pI=>Boolean 类型的谓词,f 是一个并发函数 输入I=>Promise[I]

该方法在没有注释的情况下编译。

有什么提示吗?谢谢

【问题讨论】:

    标签: scala tail-recursion scalaz promise


    【解决方案1】:

    您的方法根本不是递归的。 res 是可能在另一个线程中运行的计算。就您的方法而言,res map p flatMap f 将立即返回一个承诺。 repeat 的重复将发生在不同的过程中。

    用更简洁的术语来说,Promise 是一个延续单子,flatMap 调用会自动为您转换为延续传递样式。

    【讨论】:

      【解决方案2】:

      虽然这看起来是尾递归,因为调用在代码中只出现一次,但您有不止一个递归调用 - 一个用于集合中的每个元素。至少这是编译器看到的。 (假设这是某个集合上的 flatMap;我不知道 p 会返回什么)

      您将递归作为匿名函数传递到某处。没有人知道它会多久执行一次。

      【讨论】:

      • 感谢您的回答。但是你知道我如何在不阻塞的情况下解决这个问题吗?
      • 很抱歉,我对 scalaz 不熟悉。我只是试图找出您代码中的 p 调用是什么但失败了。你能想出一个使用 while 循环的程序版本的代码吗?如果这不可能,就不可能有 tco。
      • "集合中的每个元素一个。至少这是编译器看到的。"不正确,恕我直言:Promise 不是一个集合,编译器只看到一个调用(不在尾部位置)。但是,第二段既正确又足以解释为什么这不是尾递归。
      猜你喜欢
      • 2014-02-04
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多