指定要与 List.sum 一起使用的列表参数的问题

Issue with specifying list parameter to use with List.sum

我刚刚涉足 F#,我正在尝试编写自己的简单函数(在 fsx 文件中,使用 F# Interactive window 到 运行 它)作为一个练习,将采用一个 int 类型的列表和 return 这个列表的总和,使用 List.sum:

let sumMyList myList = List.sum myList

这个(很明显)有错误

Could not resolve the ambiguity inherent in the use of the operator ( + ) at or near this program point. Consider using type annotations to resolve the ambiguity.

所以我想我会将 myList 参数的类型指定为 List<int>:

let sumMyList myList:List<int> = List.sum myList

现在我有错误:

The type List<int> does not support the operator +

List.sum 的 F# 文档说

List.sum : ^T list -> ^T (requires ^T with static member (+) and ^T with static member Zero)

我认为 int 类型支持 + 运算符,如果我支持

List.sum [1;2;3]

一切正常,因为 [1;2;3]List<int>

我错过了什么?如何将参数指定为 int 类型列表?

您缺少括号,否则您指定的是 return 值的类型:

let sumMyList myList:list<int> = List.sum myList

应该是

let sumMyList (myList:list<int>) = List.sum myList

你也可以这样指定:

let sumMyList myList:int = List.sum myList

要以通用方式定义它,应将其声明为内联:

let inline sumMyList myList = List.sum myList

答案是我指定的类型完全错误。

突然有了干脆做的想法

[1;2;]

并在 F# Interactive window 中查看它(Alt + # 只是 运行 那一行)。它打印:

val it : int list = [1; 2]

看起来我仍然在使用 C# - 在 F# 中,int 列表被指定为 int list,而不是 List<int>

我已将我的功能更改为:

let sumMyList (myList: int list) = List.sum myList

现在可以按预期工作了。

问题是编译器需要在编译时解决使用哪个数值运算 sumMyList - 它可以是 int、float 或其他(甚至自定义)类型,所有这些都需要编译器生成不同的代码。

您可以使用类型注释指定类型(以及来自@Gustavo 的答案)显示您可以执行此操作的所有选项。

另一种选择是将函数标记为 inline,这样可以将它用于不同的类型(编译器将内联它,然后为每次使用函数选择实际类型) :

let inline sumMyList myList = List.sum myList