链接列表样式函数调用的CPS样式

时间:2018-12-13 06:28:40

标签: scala functional-programming continuation-passing

我正在尝试将以下代码转换为延续传递样式。该代码最初返回了String,所以我将其更改为调用需要String的continue lambda。我想知道如何删除next字段并改用CPS样式。

class Foo(val x: Double) {
  var next: Foo = _

  def bar(y: Double, returnLambda: (String => Unit)): Unit = {
    if (x * y > 0) {
      returnLambda("Bad")
    } else if (next == null) {
      returnLambda("Good!")
      next = new Foo(y)
    } else {
      next.bar(y, returnLambda)
    }
  }
}

1 个答案:

答案 0 :(得分:2)

您似乎在构建Foo值的单链接列表;只要新值的符号与现有值不同,就会在列表末尾添加新值。

在实用方法中,您不会将列表管理嵌入到列表中的对象中。相反,您将单独维护一个列表var next: List[Foo],并通过以下方式执行追加:

if ( next.all( _ * y <= 0) )
  returnLambda("Bad")
else {
  returnLambda("Good")
  next = next :+ Foo(y)
}

由于我们已经简化了列表操作,所以使用CPS失去了好处;您可以简单地返回字符串“ Good”或“ Bad”。

假设您确实非常需要CPS,则可以通过将next字段移到伴随对象中来删除它:

object Foo {
  val listOfFoo: ListBuffer[Foo] = ListBuffer[Foo].empty

  def bar(y: Double,  returnLambda: (String => Unit)): Unit = 
    if ( listOfFoo.all(_ * y <= 0) )
      returnLambda("Bad")
    else {
      listOfFoo += Foo(y)
      returnLambda("Good")
    }
}