ブロック内でreset
必要なのは正しいですか?shift
私はそれを試し、次のものを手に入れました:
scala>リセット{} エラー:cps変換できません式():引数を入力[Unit、Unit、Nothing] メソッドshiftUnitの型パラメーターの境界に準拠していません[A、B、C>:B]
妥当に見えますが(内部のreset
ないブロックshift
は「デッドコード」であり、実行されることはないため)、エラーはわかりません。
エラーメッセージの正確な意味は何ですか?
ブロック内でreset
必要なのは正しいですか?shift
私はそれを試し、次のものを手に入れました:
scala>リセット{} エラー:cps変換できません式():引数を入力[Unit、Unit、Nothing] メソッドshiftUnitの型パラメーターの境界に準拠していません[A、B、C>:B]
妥当に見えますが(内部のreset
ないブロックshift
は「デッドコード」であり、実行されることはないため)、エラーはわかりません。
エラーメッセージの正確な意味は何ですか?
私は同意しません、その中のコードは。reset
なしでは死んでいshift
ます。実際reset
には、継続の境界を定義するだけです(これは、継続と呼ばれるためです)。内部にどこかにあり、継続関数を呼び出さない場合、コードは無効になります。例えば:shift
reset
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
後のコードは、を呼び出していないため、shift
デッド( )です。println(3)
k(Unit)
一方、それreset
は本体から特別なリターンタイプを期待しているようです-アノテーションで@cpsParam
注釈が付けられたものです。reset
メソッドの定義を確認できます。
def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
そして、メソッドが期待するshift
ものを生成します。メソッドreset
の定義は次のとおりです。shift
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
ただし、その中で電話をかけreset
なくても使用できshift
ます。このトリックはそれを行います:
def foo[T](body: => T @cps[Any]) = reset(body)
foo {
println("it works")
}
@cps
のエイリアスを入力するだけであることに注意してください@cpsParam
。ここにその定義があります:
type cps[A] = cpsParam[A, A]