私は、scala の継続に関する複雑な型付けの問題に頭を悩ませようとしてきました。継続パッケージの参照ドキュメントを含め、私が見つけることができるすべての資料を読んでいます。私はそれをある程度理解していると思います。
それについての私の理解(および私の質問の一部)は、このプログラムによって最もよく要約できると思います。
package com.whatever;
import scala.util.continuations._;
object methods {
/* The method takes an Int as its parameter. Theoretically, at some point in the future,
* it will return a Float to the remainder of the continuation. This example does it
* immediately but doesn't have to (for example it could be calling a network service
* to do the transformation)
*
* Float @cpsParam[Unit,Float] means that whatever part of the reset{} that is captured
* as a closure should receive a Float and needn't return anything (would it be meaningful
* if Unit were something else?)
*
* The reason I have to return 0.toFloat is so the compiler can properly type the
* method. That zero will never go anywhere. Is this a sign I'm doing it wrong?
*/
def method1(param:Int): Float @cpsParam[Unit,Float] = shift { cb:(Float=>Unit) =>
cb(param.toFloat);
0.toFloat;
}
/* This method is basically identical but returns a String instead of a Float (Again,
* theoretically this would be done by a network service and cb would be called at some
* point in the future.
*/
def method2(param:Int): String @cpsParam[Unit,String] = shift { cb:(String=>Unit) =>
cb(param.toString);
""
}
}
object Main {
def main(args:Array[String]):Unit = {
reset {
val f = methods.method1(5);
println(f);
}
}
}
ちなみに、StackOverflow が scala をハイライトしないのは犯罪です!(私は訂正しました。実際にはかなり良い仕事をしますが、ライブプレビューではそうではありません)
私の質問は次のとおりです。
- 上記のプログラムのコメントから判断すると、scala の CPS についての私の理解に欠けているものは何ですか?
Unit
のように望んB
でいない状況はあります@cpsParam[B,C]
か? - 上記のプログラムはコンパイルされ、機能します (出力され
"5.0"
ます)。しかし、私が混乱を引き起こしている現在直面している問題は、ブロックを変更してafterreset
を呼び出そうとするときです。method2
method1
(明らかに、リストの直後にコード ブロックを配置することはできません)
reset {
val f = methods.method1(5);
println(f);
val s = methods.method2(42);
println(s);
}
これを行うと (これは非常に単純なことのように思えます)、リセット時に次のコンパイラ エラーが発生します (これは scala 2.10 Milestone 2 です)。
illegal answer type modification: scala.util.continuations.cpsParam[Unit,Float] andThen scala.util.continuations.cpsParam[Unit,String]
これは、「最初のシフトは Float を返し、2 番目のシフトは String を返しますが、それはできない」という意味だと解釈します。これは正確ですか?同じ戻り値の型でない限り、CPS を使用して 2 つ (またはそれ以上) のことを連続して実行できないということですか? それは一種の深刻な制限のように思えるからです。私は、1) これを可能にする何かが欠けているか、B) CPS でそれが不可能である明白な理由が欠けている、のいずれかだと思います。しかし、それはどれですか?
scala の CPS を理解するために、ポスドクの学生である必要はないと感じ始めています。しかし、私は確かにまだそこにいません。