何Scala continuations、なぜ使うのですか。
-
19-09-2019 - |
質問
活動を終えました プログラミングスカラ, "って、将来への変化とスカラ2.7 2.8.ものと思われる最も重要なのcontinuationsプラグインがかわからないか、有用などにどのよう。私は見ることで非同期I/Oが、なんと調べることができうのではないでしょうか。により資源を対象はこれらの:
このようスタックオーバーフロー:
残念ながら、これらの参考にして定義continuationsは何の為にシフト/リセット機能することになっているのですが、いつ参照のこと。していきたいへんかの事例を論文(または、いくつ方法教えてくれるので助かりますできにラインを通して一つのサンプル。でもこの一から第三の記事:
reset {
...
shift { k: (Int=>Int) => // The continuation k will be the '_ + 1' below.
k(7)
} + 1
}
// Result: 8
なぜそのような結果8?ころ助けてくれます。
解決
reset
とshift
を説明しのマイブログ行うので、あなたは再びそれを読むことをお勧めします。
私も私のブログにポイントもう一つの良いソースは、/ <継続渡しスタイル上のWikipediaのエントリですA>。その一つは、それはScalaの構文を使用しませんが、これまでで、対象の最も明確で、かつ継続が明示的に渡されます。
私は私のブログでからリンクされてますが、壊れなっているようだ区切ら継続、上の紙は、使用の多くの例を示します。
しかし、私は区切りの継続のの概念の最良の例は、Scalaの群れです。だと思いますそれには、ライブラリーがの一点でのコードの実行、および残りの計算は継続となり停止します。別のホストに計算を転写し、この場合には、停止した演算結果に(アクセスされた変数の値)を返す
- ライブラリは、その後、何かを行います。さて、あなたはScalaのページにも、簡単な例を理解するため、の行うの私のブログを読んでいません。その中で私はが唯一のの結果は8
である理由のため、これらの基本を説明するに関係しています。
他のヒント
また、既存の説明となる効果を説明するのによい希望です。これは明らかにするものとする。) っていないのに使用continuationsます。
時継続機能 cf
は:
- 実行スキップ以上の他の
shift
ブロックが再び始まるので- パラメータに渡される
cf
は何か、というshift
ブロック"評価"として執行が続いています。このできごとに異なる呼び出cf
- パラメータに渡される
- 執行を続けていま
reset
ブロックでそのまま呼び出しreset
がない場合はブロック)- の結果
reset
ブロック(またはパラメータreset
()がない場合はブロック)cf
を返します
- の結果
- 実行後の
cf
月末までのshift
ブロック - 実行スキップで
reset
ブロック(または電話でリセット?)
この例では、フォローの文字はAからZ
reset {
// A
shift { cf: (Int=>Int) =>
// B
val eleven = cf(10)
// E
println(eleven)
val oneHundredOne = cf(100)
// H
println(oneHundredOne)
oneHundredOne
}
// C execution continues here with the 10 as the context
// F execution continues here with 100
+ 1
// D 10.+(1) has been executed - 11 is returned from cf which gets assigned to eleven
// G 100.+(1) has been executed and 101 is returned and assigned to oneHundredOne
}
// I
この版画:
11
101
ただし、標準的な例から 研究論文 のためのスカラの区切りcontinuationsいては、その機能入力 shift
指定の名前 f
これは匿名のままです。
def f(k: Int => Int): Int = k(k(k(7)))
reset(
shift(f) + 1 // replace from here down with `f(k)` and move to `k`
) * 2
のScalaプラグイン変換この例のように計算の入力引数を reset
から各 shift
のメソッドの呼び出し reset
は 交換 の機能(例えば f
)入力 shift
.
交換時に計算する 移 (移動)機能 k
.の機能 f
入力機能 k
, では、 k
含む 交換を計算 k
入力 x: Int
, の計算 k
置き換え shift(f)
と x
.
f(k) * 2
def k(x: Int): Int = x + 1
るには、以下と同じ効果があります:
k(k(k(7))) * 2
def k(x: Int): Int = x + 1
注のタイプ Int
の入力パラメータ x
(の種類の署名 k
による、タイプシグニチャーの入力パラメータの f
.
他の 借入 例の概念的に同等の抽象化、すなわち read
の機能入力 shift
:
def read(callback: Byte => Unit): Unit = myCallback = callback
reset {
val byte = "byte"
val byte1 = shift(read) // replace from here with `read(callback)` and move to `callback`
println(byte + "1 = " + byte1)
val byte2 = shift(read) // replace from here with `read(callback)` and move to `callback`
println(byte + "2 = " + byte2)
}
このように変換され、論理的に同等のもの
val byte = "byte"
read(callback)
def callback(x: Byte): Unit {
val byte1 = x
println(byte + "1 = " + byte1)
read(callback2)
def callback2(x: Byte): Unit {
val byte2 = x
println(byte + "2 = " + byte1)
}
}
この解明のコヒーレント共通の抽象化したややobfuscated事前に発表されます。例えば、標準の最初の例で示した 研究論文 として匿名の機能の代わりに私の名前 f
, ることになりませんでしたすぐに明らかにいった抽象的に類似している read
の 借入 第二の例です。
このように区切りcontinuationsを作成した幻の逆転の制御から"きたいなので外部からの reset
"を呼びかけられます。 reset
".
注意の戻り値の型 f
ですが、 k
いませんが、必要なと同じ戻り値の型 reset
, ( f
の自由を宣言する意の戻り値の型 k
どの f
返品と同じタイプ reset
.数理計算上の差異の処理のため read
や capture
(参照 ENV
ます。
区切りcontinuationsない暗黙のうちに反転の制御状態、例えば read
や callback
されています。このように、呼び出し側が作成できませんreferentially透明な表現となってい コ(a.k.a.透明な制御を目的と意味論.
まで明示的に達の純粋な機能の区切りcontinuations.
def aread(env: ENV): Tuple2[Byte,ENV] {
def read(callback: Tuple2[Byte,ENV] => ENV): ENV = env.myCallback(callback)
shift(read)
}
def pure(val env: ENV): ENV {
reset {
val (byte1, env) = aread(env)
val env = env.println("byte1 = " + byte1)
val (byte2, env) = aread(env)
val env = env.println("byte2 = " + byte2)
}
}
このように変換され、論理的に同等のもの
def read(callback: Tuple2[Byte,ENV] => ENV, env: ENV): ENV =
env.myCallback(callback)
def pure(val env: ENV): ENV {
read(callback,env)
def callback(x: Tuple2[Byte,ENV]): ENV {
val (byte1, env) = x
val env = env.println("byte1 = " + byte1)
read(callback2,env)
def callback2(x: Tuple2[Byte,ENV]): ENV {
val (byte2, env) = x
val env = env.println("byte2 = " + byte2)
}
}
}
これは音のため、明示的な環境です。
Tangentially、Scalaのないウのグローバル型推論るものとし、これによってかな支援を暗黙的に吊るした状態monadの unit
(この戦略のための隠され、明示的な環境でウのグローバル(Hindley-ウ)の型推論によ サポートしておりませんのダイヤモンドに複数の仮想相続.
継続後で呼び出される、計算の状態をキャプチャします。
シフト発現を出て関数としてリセット発現を残すとの間の計算を考えます。この機能をkと呼ばれるシフト式の内部では、それは継続です。あなたも、複数回、後でそれを呼び出し、それを周りに渡すことができます。
私>は、リセット式の戻り値は=の後にシフト式の中の式の値であると思いますが、これについては私はかなりよく分からない。
あなたが関数のコードのではなく、任意の非局所的な部分を包むことができ、継続してようにします。これは、そのようなcoroutining又はバックトラッキングなどの非標準の制御フローを実装するために使用することができる。
だから、継続は、システムレベルで使用する必要があります。アプリケーションコードを介してそれらを散水することは、これまで可能性はgotoを使用して、最悪のスパゲッティコードよりもはるかに悪い悪夢のための確認のレシピ、となります。
免責事項:の私はスカラ座での継続の深い理解に何を持って、私はただの例を見て、スキームからの継続を知っているからそれを推測されていない
。私の視点からは、最良の説明がここに与えられました: HTTP ://jim-mcbeath.blogspot.ru/2010/08/delimited-continuations.htmlする
例の一つます:
もう少し明確に制御フローを表示するには、これを実行することができます コードスニペット:
reset {
println("A")
shift { k1: (Unit=>Unit) =>
println("B")
k1()
println("C")
}
println("D")
shift { k2: (Unit=>Unit) =>
println("E")
k2()
println("F")
}
println("G")
}
ここで上記のコードが生成する出力です。
A
B
D
E
G
F
C
(最近のである2016年度)の記事Scala continuationsは:
"時間旅行Scala:CPSにScala(スカラの継続など)"より
Shivansh Srivastava(shiv4nsh
).
思いのまま Jim McBeath's 第 記 ドミトリー Bespalov's 答え.
それではまず最初に、記述するContinuationsはこのように:
続きを抽象表現の制御状態をコンピュータプログラム.
なのでこの正確な意味では、データ構造を表現する計算の過程で与えられた点のプロセスの実行;作成したデータ構造とアクセスできるようにプログラミング言語ではなく、隠されているランタイム環境です。説明すれば更に対するパルス長&スポットの最もクラシックの例では、
うん、キッチンの前には冷蔵庫、考えて荷しました。ご利用の継続が貼り付けおけます。
その一部のコン、冷蔵庫、自分をサンドイッチ、座机に置ける簡単操作の串刺機。
きの呼び出しは引き続きポケットには、まだまだ立ちの前には冷蔵庫、考えて荷しました。だが幸いにあり、サンドイッチのカウンターでは、すべての材料を使用してください。そのまま食べます。:-)この説明では
sandwich
の一部である、 プログラムデータ 例えば、オブジェクトのヒープ)すると、割としっかりとした上で呼び出す"make sandwich
"常に復帰したり、人と呼ばれる"make sandwich with current continuation
"ルーチンを作成する、サンドイッチに続いて実行がでしょう。
もっとも、発表しました 月2014年Scala2.11.0-RC1
しのためのユーティリティのモジュール: scala-スイング, scala-continuations.
2.12あまり使わないのでわかりませんしない場合は新しいメンテナが.
し続けを維持、その他のモジュール(スカーラ-デscala-パーサー-combinatorsではまだぞよろしくお願い申し上げます。