私は Scala の継続に不慣れで、scala 言語全般に比較的慣れていません。
Scala の継続で遊んでみましたが、次のコードを書きました。
case class MyException(msg:String) extends Exception
def go:Int = reset {
println("enter your input")
val my_check = //try
{
val user_input = readLine()
if (!user_input.matches("\\w+")) {
throw new MyException("illegal string: " + user_input)
}
shift {
k: (Boolean => Int) => {
if (user_input == "true") {
k(true)
}
else if (user_input == "false") {
k(false)
}
else {
// don't even continue
0
}
}
}
}
// catch {
// case MyException(msg) => false
// }
if (my_check) {
println("TRUE")
1
}
else {
println("FALSE")
-1
}
}
println(go)
コードは期待どおりに機能しました。ユーザーが英数字以外の文字列を入力すると aMyException
がスローされ、ユーザーが「true」を入力するとコードは に続きmy_check = true
、ユーザーが「false」を入力するとコードは に続きmy_check = false
、ユーザーが英数字を入力すると「true」でも「false」でもない文字列は、go
関数は 0 で終了します。
次に、コードの一部を try-catch ブロック (コメントがある場所) でラップしようとしましたが、コンパイルは次のように失敗しました。
エラー: 非 cps 位置に cps 式が見つかりました
val my_check = 試す
例外を継続に「注入」することに問題があることは理解していますが、シフトされた呼び出しを単純に try-catch ブロック内に配置できないのはなぜですか?
私が計画しているフレームワークでこれが必要です。プログラマーは、自分のコードが継続形式で使用されていることに気付かないでしょう (彼は「通常」と考える関数を呼び出しますが、実際にはshift
)。
明らかに、シフトされた呼び出し自体は例外を発生させませんが、try-catch ブロック内で関数を呼び出すことができるようにする必要があります。
この問題はControlContextで解決できますか? 値にいくつかの「入力」ルールを追加すると役立ちますか (おそらく@cps[..]を使用)?
アクターを使用する別の方法についてはすでに考えているので、それに対するクレジットは得られません :)
ありがとう、
(PS 私は Scala 2.9.2 を使用しており、明らかに-P:continuations:enableフラグを使用しています)