11

ブロック内でreset必要なのは正しいですか?shift私はそれを試し、次のものを手に入れました:

scala>リセット{}
エラー:cps変換できません式():引数を入力[Unit、Unit、Nothing]
メソッドshiftUnitの型パラメーターの境界に準拠していません[A、B、C>:B]

妥当に見えますが(内部のresetないブロックshiftは「デッドコード」であり、実行されることはないため)、エラーはわかりません。

エラーメッセージの正確な意味は何ですか?

4

1 に答える 1

4

私は同意しません、その中のコードは。resetなしでは死んでいshiftます。実際resetには、継続の境界を定義するだけです(これは、継続と呼ばれるためです)。内部にどこかにあり、継続関数を呼び出さない場合、コードは無効になります。例えば:shiftreset

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]
于 2011-05-27T17:18:29.827 に答える