mutable変数はクロージャに閉包できない
let makeFiboClosure (a, b) = let mutable t = (a, b) fun () -> let x,y = t in t <- (y, x+y); x
makeFiboClosure は、クロージャを作る関数です。評価するとレキシカル変数なタプル t を更新しながら数列を生成する無引数のクージャを返します。
コンパイルしてみたら...
error FS0407: The mutable variable 't' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.
ダメでした。
「mutable 変数は クロージャでキャプチャできない。ref でヒープにアロケートして ! で参照してね」
なんて親切なエラーメッセージなんだ。
というわけで。完成。
let repeatedly f = seq {while true do yield f ()} let makeFiboClosure (a, b) = let t = ref (a, b) fun () -> let x,y = !t in t := (y, x+y); x let fibo = makeFiboClosure >> repeatedly
(1, 1) |> fibo |> Seq.take 10 |> Seq.toList ;; => [1; 1; 2; 3; 5; 8; 13; 21; 34; 55]
関数型プログラミングっぽいね!*2