scalaの限定継続 その2

限定継続をいろいろ実験中。

if文や try/catch の中に shift を置く場合、どの分岐経路を通っても、ifやtryの戻り値型に同じ cpsParam のアノテーションが付くようにしなければいけない。

この例では、tryの中に shift を置いた例。try中のshiftは戻り値型が @cpsParam[String, String] なので、catchも @cpsParam[String, String] になるように shift を置かないといけない。

import scala.util.continuations._;

object Demo2 {

  def main(args: Array[String]){

    val result = reset {

      // (1)

      try {

        val b = shift { ctx: (String=>String) =>
          // (2)
          val c1 = ctx("abc");
          // (7) c1 = "ERROR"
          val c2 = ctx("ABC");
          // (11) c2 = "ABCdef"
          c1 + ":" + c2; // (12) return "ERROR:ABCdef"
        }

        // (3) b = "abc"
        // (8) b = "ABC"

        if(b == "abc"){
          // (4)
          throw new Exception();
        }

        // (9)
        b + "def"; // (10) return "ABCdef"

      } catch { case e =>
        // (5)
        shift { ctx: (String=>String) =>
          // (6)
          "ERROR";
        }
      }

    }

    // (13) result = "ERROR:ABCdef"

    println(result);

  }

}

コメントの中の番号は、実行される順序で、番号の右にその時の変数の値などを示す。tryの中のshiftでctxを2回呼び出しているので、(3)(8)の箇所は2回通過する。1回目はその下のif文にマッチしcatchブロックに進み、2回目はif分にマッチせずに次に進む。

catchの中にもshiftを書かないといけないのはスマートじゃない気がするが、こんなことしないといけないのか。他に方法はないのか。