継続渡し
継続を受け取って継続を返すような関数の書き方
引数の渡し方の文脈mrsekut.icon
関数呼び出し時の目線
関数を呼び出すときに、「継続も渡す」ように書き換える
関数定義時の目線
「ある関数fを継続渡しにする」と言えば、それは
引数にcontを追加
returnする直前にcontを適用する
の2つの変更を加えることと同義
例
こういう関数を継続渡しに変えてみる
これは直接スタイル
code:hs
process :: Int -> Int -> Int
process elt seed = elt : seed
継続渡しにする
code:hs
processWithCont :: Int -> Int -> (Int -> Int) -> Int
processWithCont elt seed cont = cont $ elt : seed
継続渡しに書き換えることに依って得られる嬉しさ
https://jutememo.blogspot.com/2011/05/haskell-cps.html#:~:text=6.%20リストの平坦化
一例
継続渡しで書くことでメモリ消費を抑えられる(言語に依る)
日本語で説明するのがむずいmrsekut.icon
↓はたぶんめっちゃ分かりづらいと思うが割と説明を諦めている..mrsekut.icon
継続渡しで関数を定義することで、関数の呼び出しが終わった後に、
呼び出し元へ戻る、のではなく、
継続へ移行する、のように動作する
例えば上の例では、関数mainが、
processを呼び出すと、processの実行が終了したらmainへ戻ってくるが、
processWithContを呼び出し、それが終了すると、mainへ戻るのではなく、contが呼び出される
こういった挙動があるため、末尾呼び出しの除去によって、メモリ消費を抑えられる
その言語がこの最適化をサポートしているかどうかで恩恵を受けられるかどうかは異なる
継続を受け取って、継続を返さなければ処理は中断する
/mrsekut-b/継続わからん#60a7b26e198270000044b5a0