無差別に技術をついばむ鳥

情報処理技術全般を気まぐれにつつくゆるいブログです

F#をつつく5ー再帰関数。ループは再帰というけれど・・・

F#は資料が少ないから、OCamlに合わせて再帰関数を紹介するピヨ。関数型言語は、関数型と呼ぶだけあって、基本的にはループよりも関数呼び出しでプログラムを組むことが多いんだ。サンプルとして0.1つつきで紹介したHelloプログラムを見てみよう。


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を参考にしていて、パフォーマンスに関連することだからおそらく実装すると思う。だからボクも再帰関数を積極的に書いていくよ。
今回はこれでおしまい。
別窓 | F# | コメント:0 | トラックバック:0 | ∧top | under∨
<<中の人の徒然草52 | 無差別に技術をついばむ鳥 | F#をつつく4−型推論。みなまで言うまい。>>

この記事のコメント

∧top | under∨

コメントの投稿

 

管理者だけに閲覧
 

この記事のトラックバック

∧top | under∨
| 無差別に技術をついばむ鳥 |