末尾再帰
tail recursive
末尾呼び出しの特殊パターン
末尾呼び出しでかつ、その呼び出しが再帰になっているもの
具体例
末尾呼び出しの具体例から持ってくると ref 末尾呼び出し#609d32161982700000c07cbe
code:example.c
function foo(data) {
a(data);
return foo(data);
}
このfooは末尾呼び出しで、かつ再帰呼び出しをしている
Haskellでの例 ref
code:hs
sum :: Num a => a -> a
sum xs = sum' xs 0
where
sum' [] r = r
sum' (y:ys) r = sum' ys (y+r)
rは状態として機能しているmrsekut.icon
sum'の定義が末尾再帰になっている
=のすぐ右にsum'(自分自身)が来ているのがポイント
= sum' ...になっている
末尾再帰じゃない例
code:hs
sum [] = 0
sum (x:xs) = (+) x (sum xs)
真末尾再帰
https://qiita.com/takl/items/6d3319e835a27fc5e4b9#真正末尾再帰
相互末尾再帰
http://practical-scheme.net/docs/tailcall-j.html
Scheme言語読めるようになったらまた読みたいmrsekut.icon
末尾再帰の最適化
#??
ただの再帰関数を、末尾再帰に変換すること、はなんと呼ぶのか
継続で言う、CPS変換的な
末尾再帰にするのが嬉しい場合
よくわかっていない #??
https://kazu-yamamoto.hatenablog.jp/entry/20110908/1315473844
この記事を雑に読む感じ以下の場合で話が全く異なる
その言語が遅延評価をするかどうか
その言語が末尾再帰の最適化をするかどうか
その関数がリストを生成するのか、数値を生成するのか
『基礎からわかるElm』.icon pp.82-83にもちょっと書いてる
https://eed3si9n.com/herding-cats/ja/tail-recursive-monads.html
monad