F# 这可以用无点样式表示吗?
给出了以下表达式来求一个IEnumerable数的和:F# 这可以用无点样式表示吗?,f#,lambda-calculus,pointfree,F#,Lambda Calculus,Pointfree,给出了以下表达式来求一个IEnumerable数的和: let sum l = l |> Seq.reduce(+) //version a 有没有可能像这样消除争论 我从F#编译器(FS0030)那里得到了一个错误,我似乎记得看到了一些关于“eta转换”的信息,但不幸的是,我对lambda calc的了解太有限,无法理解eta转换是如何涉及的 在版本b中是否可以消除该参数 有人能给我指一下解释eta转换的文献,以及它在这段特定代码中是如何发挥作用的吗 FS0030: 标准输入(1,5
let sum l = l |> Seq.reduce(+) //version a
有没有可能像这样消除争论
我从F#编译器(FS0030)那里得到了一个错误,我似乎记得看到了一些关于“eta转换”的信息,但不幸的是,我对lambda calc的了解太有限,无法理解eta转换是如何涉及的
在版本b中是否可以消除该参数
有人能给我指一下解释eta转换的文献,以及它在这段特定代码中是如何发挥作用的吗
FS0030:
标准输入(1,5):错误FS0030:值限制。值“sum”已被删除
推断为具有泛型类型
val sum:('''u a->int)当''u a:>seq'时,要么显式设置'sum'的参数,要么,如果您不希望这样做的话
泛型,添加类型批注
可以使用无点样式进行此操作,但需要添加(单态)类型注释:
let sum : int seq -> int = Seq.reduce (+)
“Eta转换”只是指添加或删除参数。您遇到的问题称为值限制。在ML语言中,声明为值的值(即声明时没有显式参数)不能具有泛型类型,即使它具有函数类型。是一些相关的文献。其思想是防止ref单元格保存不同类型的值。例如,如果没有值限制,将允许以下程序:
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#不允许通用的值。但是,它完全允许通用的函数。让我们通过添加一个伪
单位
参数,将sum
转换为一个函数:
let sum_attempt1() = Seq.reduce (+)
let v1 = [1.0; 2.0] |> sum() // float
// inferred by first usage:
// val sum_attempt1: unit -> (seq<float> -> float)
l
在版本a中做什么?请您提醒我们(在问题正文中)什么是FS0030
?对于版本a,您的意思是let sum l=Seq.reduce(+)l
?从错误中可以看出(并且可能知道),F不允许通用值。无点样式在F#中仅得到有限的支持。@petebu谢谢——代码是固定的。谢谢@kvb;我还想知道是否有人能给我提供更多关于eta转换的信息。可能简单地说:ML语言中的函数可以是闭包,而且由于ML是静态类型的,所以在使用之前必须在引用环境中消除类型的歧义。有趣的想法——在函数上添加内联。
let sum_attempt1() = Seq.reduce (+)
let v1 = [1.0; 2.0] |> sum() // float
// inferred by first usage:
// val sum_attempt1: unit -> (seq<float> -> float)
let inline sum() = Seq.reduce (+)
// val sum: unit -> (seq<'a> -> 'a)
// Use
let v1 = [1; 2] |> sum() // int
let v2 = [1.0; 2.0] |> sum() // float
let v3 = ["foo"; "bar"] |> sum() // string