F# の sum
関数はオーバーフローチェックします。なので例えば次のコードはオーバーフロー例外が出ます。
Seq.sum <| seq { 1 .. 1000000 } // OverflowException
F# は適切な型を宣言すればいろいろな関数が利用できます。整数をラップする型を作ってオーバーフローしない方法を試みます。
[<Struct>] type Int32 (value : System.Int32) = member this.Value = value static member Zero = Int32 (0) static member One = Int32 (1) static member (+) (x : Int32, y : Int32) = Int32 (x.Value + y.Value)
.NET Framework 標準の型と名前がかぶっているのは行儀が悪い作法ですが,ここでは気にしないでください。これを使って, sum
を実行してみます。
Seq.sum <| seq { Int32 (1) .. Int32 (1000000) } (* |> fun s -> s.Value // 1784293664 *)
オーバーフローしても問題なく和が計算できました。
おまけ
上記の方法はパフォーマンスが悪いです。次のようにした方が 8 倍くらい速いです。
Seq.fold (+) 0 <| seq { 1 .. 1000000 } // 1784293664