- takayutsch
- 1064
- 6
- 1
- 0
@mametter たとえば reset (3 + shift (const 12)) の答は 12 ですけど、3 + callcc (const 12) の答は15ですよね
2016-03-14 22:41:48@mr_konn そうか。継続を呼ばないとそうなりますね。でも reset (shift (fun k -> (k 1) + 2)) は 3 だけど callcc (fun k -> (k 1) + 2) は 1 になるので単純に reset 即 shift でもない気がする
2016-03-14 22:47:47@mr_konn callcc M は全体を reset で囲った上で shift (fun k -> k M) と同じ?(ただしプログラムは最後に exit するので reset には到達し得ないこととする)
2016-03-14 22:54:55@mr_konn 型とかいう発想を忘れていた。普通の継続の型は t -> \bot です。部分継続でも同じだと思いますが、プログラム全体を reset で囲むのは仮想的にはできるけど実際にはできなくて現実の型システムは通らないかも?という話かしら?
2016-03-14 23:08:38@mametter たとえば callcc で囲われた部分全体が型 t だとした時の継続が t → ⊥ だということですよね。それはいいんですけど、この時 callcc M の M は (t → ⊥) 型を引数にとるので、k M って道理に合わないのでは……?と思ったのです
2016-03-14 23:12:34@mr_konn 普通に間違えてますね。callcc M は shift (fun k -> k (M k)) と同じか
2016-03-14 23:15:26@mametter @mr_konn call/cc (λk. (k 1) + 1) + 2は3ですが、reset (shift (λk. k ((k 1) + 1)) + 2)は6ですし、reset (shift (λk. k ((k 1) + 1))) + 2は4です。
2016-03-14 23:27:09@cocoa_ruto @mr_konn callcc (λk. (k 1) + 1) + 1 は reset (exit (shift (λk. k ((k 1) + 1)) + 2)) と同じという主張です。exit は引数を評価してプロセス終了するような何か
2016-03-14 23:30:57@mametter @cocoa_ruto 手で展開していくと、exit が正格評価と定められているのでちゃんと 3 を返して終わる筈ですね。
2016-03-14 23:41:40@mametter @mr_konn exitを許すならばそうなります。ただしネストした場合はexitではなく、「1つ外側の部分継続」になります。 gist.github.com/taku0/b3dd6298… で、その「1つ外側の部分継続」をどうやって取るのかという問題に行き着きます。
2016-03-15 00:00:06@cocoa_ruto @mametter あーネストした場合については全然考えてなかったですね……。そもそも shift/reset で call/cc を表現しようというのが間違いという事なんですかね?
2016-03-15 00:04:02@mr_konn @mametter 「1つ外側の部分継続」を動的スコープ変数に入れるとすれば、「call/ccとは、exit+shift/reset+動的スコープ変数」と言えます。
2016-03-15 00:09:14@mr_konn @mametter 別の捉え方としては、部分継続が外側からk1, k2, k3であるときに、それにexitを付けて合成したexit.k1.k2.k3が普通の継続であるとも言えます(「部分」を全て繋げると「全体」になる)。
2016-03-15 00:10:39@mr_konn @cocoa_ruto @mametter プログラム内で shift/reset 使わないでください ^^ 使いたいなら、shift/reset でエンコードした callcc を使って shift/reset を定義してください
2016-03-15 00:10:49