F#をつつく5ー再帰関数。ループは再帰というけれど・・・
open System;;
let hello max =
(* recursive function *)
let rec iter count =
if count < max then begin
if count = 0 then Printf.printf "hello indre\n";
Console.Write(count.ToString() + "\t");
iter ( count + 1 )
end
in
iter 0;;
hello 10;;
Console.WriteLine("good-by");;
Console.ReadLine();;
今気付いたんだけど、全角スペースを使わないように注意してね。シンタックスエラーになるピヨ。 再帰関数の定義は、let rec iter count のところだよ。つまり・・・
let rec 関数名 インスタンス名
の形式なんだよ。関数名にの他にインスタンス名(便宜上のボクが付けた表記)なんて少し変だよね?F#はOCamlと違う所があるから試しにインスタンス名を省略してみたピヨ。そしたら・・・
やっぱり駄目でしたorz
でも親切かわからないエラーメッセージと開発ソフトのお陰で何で省略できないのかが分かったピヨ。
インスタンス名を省略してしまうと、一時情報がなくなるからなんだ。再帰関数と言う事は、今現在のデータと 関数そのもののデータが別に存在しないと、今現在何をしているのか分からなくって処理が続行できなくなるからなんだ。分かりにくいので例をあげるよ。
例えば、0~10の数値を順番に足している時のことを想像してね。この場合、足し算をするという行為は数値が何であっても変わらないから、現在値+足す数となるよね。でも、万が一現在値が分からなくなったら計算できない。
この例で分かったと思うんだけど、だからインスタンス名が必要なんだ。作業中のデータを含んだ関数と関数そのものを別にしておく理由はこれなんだよ。
話しは少し変わるけど、OCamlでは再帰関数を使用する理由として、コンパイラが 再帰関数を末尾関数に変えてくれるからなんだけど、F#の場合は正直言って分からない。でも、OCamlを参考にしていて、パフォーマンスに関連することだからおそらく実装すると思う。だからボクも再帰関数を積極的に書いていくよ。
今回はこれでおしまい。