Seq.scan で FizzBuzz

これも商を求めないでFizzBuzz。Seq.scanを使ってみたかった。

[<Test>]
let ``fizzbuzz with Seq.scan``() =

let fizzbuzz (f, b, value) n =
let f', b' = f + 1, b + 1
match f, b with
| 3, 5 -> (1 , 1 , "fizzbuzz")
| 3, _ -> (1 , b', "fizz")
| _, 5 -> (f', 1 , "buzz")
| _, _ -> (f', b' , string(n))

seq { 1 .. 100 }
|> Seq.scan fizzbuzz (1, 1, "")
|> Seq.map (function _, _, x -> x)
|> Seq.iter (printfn "%s")

Seq.scanはシグネチャを見ると次のように長くて最初ひるみましたが、使ってみるとそうでもない。

Seq.scan : ('State -> 'T -> 'State) -> 'State -> seq<'T> -> seq<'State>

変数というか値の名前にクォート(ダッシュ?)をつけるサンプルをたまに見かけるのでつかってみましたが、見にくい。。。カンマとクォートがごちゃごちゃしちゃいますね。

追記

Seq.scanって、最初に与えたStateを結果のシーケンスに含めるんですね。だから上のままだと余分な結果が入ってしまっていました。とりあえず、Seq.skip(1)を入れれば除去できる。

seq { 1.. 100 }

> Seq.scan fizzbuzz (1, 1, "")
> Seq.skip (1)
> Seq.map (function _, _, x -> x)
> Seq.iter (printfn "%s")