継続渡し
関数呼び出し時の目線
関数を呼び出すときに、「
継続も渡す」ように書き換える
関数定義時の目線
「ある関数 f
を継続渡しにする」と言えば、それは
引数にcontを追加
returnする直前にcontを適用する
の2つの変更を加えることと同義
例
こういう関数を継続渡しに変えてみる
hsprocess :: Int -> [Int] -> [Int]
process elt seed = elt : seed
継続渡しにする
hsprocessWithCont :: Int -> [Int] -> ([Int] -> [Int]) -> [Int]
processWithCont elt seed cont = cont $ elt : seed
継続渡しに書き換えることに依って得られる嬉しさ
一例
継続渡しで書くことでメモリ消費を抑えられる(言語に依る)
日本語で説明するのがむずい

↓はたぶんめっちゃ分かりづらいと思うが割と説明を諦めている..

継続渡しで関数を定義することで、関数の呼び出しが終わった後に、
呼び出し元へ戻る、のではなく、
継続へ移行する、のように動作する
例えば上の例では、関数 main
が、
process
を呼び出すと、 process
の実行が終了したら main
へ戻ってくるが、
processWithCont
を呼び出し、それが終了すると、 main
へ戻るのではなく、 cont
が呼び出される
その言語がこの最適化をサポートしているかどうかで恩恵を受けられるかどうかは異なる
継続を受け取って、継続を返さなければ処理は中断する