给定以下表达式来对 IEnumerable 的数字求和:
let sum l = l |> Seq.reduce(+) //version a
是否有可能消除争论——像这样?
let sum = Seq.reduce(+) //version b
我从 F# 编译器 (FS0030) 收到一个错误,我似乎记得看到过有关“eta 转换”的内容,但不幸的是,我对 lambda calc 的了解太有限,无法了解 eta 转换是如何涉及的。
是否可以像版本 b 一样消除这个论点?
有人可以指点我一些文献来解释 eta 转换以及它如何在这段特定的代码中发挥作用吗?
FS0030:
stdin(1,5): error FS0030: Value restriction. The value 'sum' has been inferred to have generic type val sum : ('_a -> int) when '_a :> seq Either make the arguments to 'sum' explicit or, if you do not intend for it to be generic, add a type annotation.
最佳答案
“Eta 转换”只是意味着添加或删除参数。您遇到的问题称为值限制。在 ML 语言中,一个值声明为一个值,即。没有显式参数声明,不能有泛型类型,即使它有一个函数类型。 Here是一些相关的文献。这个想法是为了防止引用单元格保存不同类型的值。例如,在没有值限制的情况下,将允许以下程序:
let f : 'a -> 'a option =
let r = ref None
fun x ->
let old = !r
r := Some x
old
f 3 // r := Some 3; returns None : int option
f "t" // r := Some "t"; returns Some 3 : string option!!!
正如 kvb 所说,如果您不打算将函数通用,那么您可以添加类型签名并使用无点样式。
关于f# - 这可以用点自由风格表达吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19117877/