这个定义为什么会返回一个函数?
我发现书中Expert F# 4.0, Fourth Edition
以下,由Don赛姆,亚当Granicz和安东尼奥奇斯泰尼诺:这个定义为什么会返回一个函数?
let generateStamp =
let mutable count = 0
(fun() -> count <- count + 1; count)
我不明白为什么这个代码创建了一个功能:
val generateStamp : (unit -> int)
它看起来我喜欢它的签名应该是
val generateStamp : int
例如,下面的代码:
let gS =
let mutable count = 0
(printfn "%d" count; count)
创建一个int值:
val gS : int = 0
据我了解它的代码(fun() -> count <- count + 1; count)
应首先评估拉姆达然后count
。所以generateStamp
的值应该只是count
,因为它在gS
的定义中。我错过了什么?
在任何F#代码块中,该块中的最后一个表达式将是该块的值。可以用两种方法之一定义一个块:缩进,或在块的表达式之间使用;
。
表达式fun() -> other expressions here
创建一个函数。由于这是let generateStamp =
下代码块中的最后一个表达式,因此这是存储在generateStamp
中的值。
您的困惑是,您认为fun()
中的表达式将立即作为generateStamp
的值的一部分进行评估,但它们不是。他们正在定义由fun()
表达式返回的匿名函数的正文。你是绝对正确的,在代码块中,count
是最后一个表达式,所以它是该函数返回的东西。但fun()
表达式创建了一个函数,该函数仅在稍后调用时称其为。它不立即评估其内容。
相比之下,表达式(printfn "%d" count; count)
是一个包含两个表达式的代码块。它是不是的一个函数,所以它会被立即评估。它的最后一个表达式是count
,所以代码块(printfn "%d" count; count)
的值是count
。由于(printfn "%d" count; count)
区块正在被立即评估,因此您可以用count
进行小心替换。所以gS
的值是count
,而generateStamp
的值是返回count
的函数。
很难选择两个非常明确的答案。我必须选择一个。一种观察:代码在括号之间的整个lambda体上更清晰:fun() - >(count Soldalma
这是句法诡计。最后的; count
部分实际上是部分的lambda,而不是其后的下一个表达式。
这里有一些简化的例子合作,通过:
let x = 1; 2; 3 // x = 3
let f x = 1; 2; 3 // f is a function
let y = f 5 // y = 3, result of calling function "f"
let f = fun x -> 1; 2; 3 // Equivalent to the previous definition of "f"
let y = f 5 // y = 3, same as above
let f =
fun x -> 1; 2; 3 // Still equivalent
let y = f 5 // y = 3, same as above
let f =
let z = 5
fun x -> 1; 2; 3 // Still equivalent
let y = f 5 // y = 3, same as above
// Your original example. See the similarity?
let generateStamp =
let mutable count = 0
fun() -> count <- count + 1; count
现在,如果你想有count
是generateStamp
的返回值,你需要把它要么外面的括号或在下line:
// The following two definitions will make "generateStamp" have type "int"
let generateStamp =
let mutable count = 0
(fun() -> count <- count + 1); count
let generateStamp =
let mutable count = 0
(fun() -> count <- count + 1)
count
'fun x - > y'是一个函数文字 - 它创建一个新的函数,但不评估它。在你的代码中,新创建的函数是返回值,所以你看到'generateStamp'的值与创建的函数具有相同的类型。 – Yawar
@Yawar - 你可能是对的,但我不明白为什么新创建的函数是返回值。为什么返回值不是一个int,因为'count'是最后一个要评估的事物,F#没有'return'关键字,总是返回最后一个评估的事物? – Soldalma
看到这个了不起的答案http://*.com/a/42430195/20371 – Yawar