generated at
継続渡し
継続を受け取って継続を返すような関数の書き方


関数呼び出し時の目線
関数を呼び出すときに、「継続も渡す」ように書き換える


関数定義時の目線
「ある関数 f を継続渡しにする」と言えば、それは
引数にcontを追加
returnする直前にcontを適用する
の2つの変更を加えることと同義



こういう関数を継続渡しに変えてみる
hs
process :: Int -> [Int] -> [Int] process elt seed = elt : seed
継続渡しにする
hs
processWithCont :: Int -> [Int] -> ([Int] -> [Int]) -> [Int] processWithCont elt seed cont = cont $ elt : seed


継続渡しに書き換えることに依って得られる嬉しさ
一例


継続渡しで書くことでメモリ消費を抑えられる(言語に依る)
日本語で説明するのがむずいmrsekut
↓はたぶんめっちゃ分かりづらいと思うが割と説明を諦めている..mrsekut
継続渡しで関数を定義することで、関数の呼び出しが終わった後に、
呼び出し元へ戻る、のではなく、
継続へ移行する、のように動作する
例えば上の例では、関数 main が、
process を呼び出すと、 process の実行が終了したら main へ戻ってくるが、
processWithCont を呼び出し、それが終了すると、 main へ戻るのではなく、 cont が呼び出される
こういった挙動があるため、末尾呼び出しの除去によって、メモリ消費を抑えられる
その言語がこの最適化をサポートしているかどうかで恩恵を受けられるかどうかは異なる



継続を受け取って、継続を返さなければ処理は中断する