F# 如何获取列表Reduce以抛出算术溢出

F# 如何获取列表Reduce以抛出算术溢出,f#,F#,因此,昨天,当作为编码练习的一部分处理一些F#代码时,另一位开发人员指出了一些有趣的事情。我们只是在做一段快速的代码来演示对列表求和。如果我这样做: [1..100000] |> Seq.sum 我得到以下错误: System.OverflowException: Arithmetic operation resulted in an overflow. at <StartupCode$FSI_0003>.$FSI_0003.main@() Stopped due to

因此,昨天,当作为编码练习的一部分处理一些F#代码时,另一位开发人员指出了一些有趣的事情。我们只是在做一段快速的代码来演示对列表求和。如果我这样做:

[1..100000] |> Seq.sum
我得到以下错误:

System.OverflowException: Arithmetic operation resulted in an overflow.
   at <StartupCode$FSI_0003>.$FSI_0003.main@()
Stopped due to error
我得到:

val it : int = 705082704

我意识到,虽然这两段代码应该达到相同的目的,但它们是非常不同的。我只是好奇是否有办法获取列表。reduce抛出OverflowException而不是给我一个糟糕的答案?

您可以使用选中运算符:

[1..100000] |> List.reduce (Checked.(+))
来自f#源代码

[<CompiledName("Sum")>]
let inline sum (source: seq< (^a) >) : ^a = 
  use e = source.GetEnumerator() 
  let mutable acc = LanguagePrimitives.GenericZero< (^a) >
  while e.MoveNext() do
      acc <- Checked.(+) acc e.Current
  acc
[]
让内联求和(来源:seq<(^a)>):^a=
使用e=source.GetEnumerator()
设可变acc=LanguagePrimitives.GenericZero<(^a)>
而e.MoveNext()做什么

acc只是现有答案的一个补充:总和
1..100000=(100001*100000)/2=5000050000=0x12A06B550
,这是一个溢出。删除溢出位:
0x12A06B550-0x100000000=0x2A06B550=705082704
[<CompiledName("Sum")>]
let inline sum (source: seq< (^a) >) : ^a = 
  use e = source.GetEnumerator() 
  let mutable acc = LanguagePrimitives.GenericZero< (^a) >
  while e.MoveNext() do
      acc <- Checked.(+) acc e.Current
  acc