Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

ScalaでCPS(継続渡しスタイル)

まるごとJavaScript & Ajax ! Vol.1を読み返してCPSを学んでみる。

  def sumIterTrump(i: Int, part: Int, cont: Int => Unit): Function2[Int, Int, Function0[Int]] = {
    if (i > 10) {
      cont(part)
      null
    } else {
      println("progress " + i + "/10")
      sumIterTrump(i + 1, part + i, cont)
    }
  }
  sumIterTrump(1, 0, {sum: Int => println("sum is " + sum)})

p198を参照。ASをScalaに書き換えたけど、本当にこれでCPSなんだろうか??
戻り値の型「Function2[Int, Int, Function0[Int]]」なんて無理矢理な気がする。
間違いがあればぜひぜひご指摘ください!


末尾再帰であることには変わりはないけど、sumIterTrumpの第3引数に関数をもらってる。
これがsumIterTrumpの処理が終了した後に実行する処理を関数として渡している。
処理が終了したあとに実行する処理 = 継続なわけで、継続を渡しているから継続渡しスタイルと。
CPS = Continuation Passing Styleね。

いつ使うの?

今回みたいな例だと、別にCPSを使わなくても末尾再帰できてしまうけど、処理によってはそのままだと末尾再帰にしづらいものがある。
そういうときにCPSを使えば、処理を末尾再帰にすることができると。


さてさて、これがContinuous Monad(継続モナド)とどうつながるのか。また勉強だね。