Array.sum 的 F# 类型推断

F# type inference with Array.sum

为什么我必须告诉 F# 我在这一行中使用的是 int 还是 float let total counts = Array.sum countslet total (counts:int[]) = Array.sum counts ?

来自 sml,我发现 F# 类型推断有点过于严格。

P.S。我对函数式语言的前景了解不多,但如果有人能启发我在野外使用哪些 F 语言,我会很感兴趣。

根据错误消息,我得到的问题是您必须将其限制为支持“+”运算符的类型。

我假设 float 和 int 都这样做,但不是默认类型 'obj' 如果您不指定数组类型,默认类型就是您得到的类型。

在 F# 中,编译是一次通过,并且(大部分)严格 feed-forward。我相信这样做是为了缩短编译时间,但我不确定。结果是在表达式 Array.sum counts 中,sum 函数不知道 counts 是什么类型,除非您添加类型注释。

您可以编写计算等效表达式 counts |> Array.sum,因为 counts 在文件中较早出现,sum 能够正确解析类型。这是 pipeline operator |> 在 F# 代码中如此常见的原因之一。

( recand 关键字允许编译器引用源文件中的内容,以允许 [=28 中的相互递归函数和类型和 member =] 定义在默认情况下是相互递归的,但这是例外。)

不是直接的答案,但您可以选择创建一个更通用的内联函数:

let inline total counts = Array.sum counts

使用必要的静态解析类型参数自动推断出 this 的类型:

> val inline total:
  counts:  ^a[] ->  ^a
    when  ^a: (static member (+) :  ^a *  ^a ->  ^a) and
          ^a: (static member get_Zero: ->  ^a)

用法:

total [|1; 2; 3|] // 6
total [|1.; 2.; 3.|] // 6.0