http://projecteuler.net/index.php?section=problems&id=2
Haskellで書くと、
fib = 1:2:[ a + b | (a,b) <- zip fib (tail fib) ] main = print (sum (takeWhile (<=4*10^6) (filter even fib)))
フィボナッチ数列の無限リストを作ってtakeWhileでぶった切るのが定番の解法です。
F#でリストでは無限リストは実現できない、のかな?代わりにSequenceというものを使うと無限リストのようなものができます。
let sq = Seq.initInfinite (fun i -> i * i) printfn "%A" (Seq.toList (Seq.take 5 sq)) // "%A"はList用のformat
これを実行すると、
[0; 1; 4; 9; 16]
Seq.initInfiniteの引数に0,1,2,...と適用したときの無限リストが作られるらしいです。Seq.takeで頭の5つを取って、Seq.toListでリストに変換して、"%A"で出力します。
けれど、これはフィボナッチ数列には使いにくいですよね。もう一つPythonのようなyieldを使う方法があります。
let count = Seq.initInfinite (fun i -> i) let sq = seq { for i in count do yield i * i } printfn "%A" (Seq.toList (Seq.take 5 sq))
コンパイラにタブ使うなと怒られてしまいました。試行錯誤を繰り返した結果、
let count = Seq.initInfinite (fun i -> i) let sq = seq { for i in count do yield i * i } printfn "%A" (Seq.toList (Seq.take 5 sq))
どうやら、インデントはスペース3つ以内で{}内は揃える、ということのようです。エディタの設定で拡張子.fsなら3タブでタブで空白入力ということにしましょうかね。
タブを使いたければソースの頭に次のように書くとよいようです。
#light "off" let count = Seq.initInfinite (fun i -> i) let sq = seq { for i in count do yield i * i done };; printfn "%A" (Seq.toList (Seq.take 5 sq))
こうするとインデントを揃えるなどはしなくてよいようです。ただし、適切に;;を入れたりループの終わりにdoneを入れたりと色々面倒なようです。
長くなったので今回はここまでにします。