I found the following in the book Expert F# 4.0, Fourth Edition
, by Don Syme, Adam Granicz, and Antonio Cisternino:
let generateStamp =
let mutable count = 0
(fun () -> count <- count + 1; count)
I could not understand why this code creates a function:
val generateStamp : (unit -> int)
It looks to me like its signature should be
val generateStamp : int
For example, the following code:
let gS =
let mutable count = 0
(printfn "%d" count; count)
creates an int value:
val gS : int = 0
As I understand it the code (fun () -> count <- count + 1; count)
should first evaluate the lambda and then count
. So the value of generateStamp
should be just count
, as it is in the definition of gS
. What am I missing?
In any block of F# code, the last expression in that block will be the value of that block. A block can be defined in one of two ways: by indentation, or with ;
between the block's expressions.
The expression fun () -> other expressions here
creates a function. Since that's the last expression in the code block under let generateStamp =
, that's the value that gets stored in generateStamp
.
Your confusion is that you think that the expressions inside the fun ()
are going to be evaluated immediately as part of the value of generateStamp
, but they're not. They are defining the body of the anonymous function returned by the fun ()
expression. You're absolutely right that inside that block of code, count
is the last expression and so it's the thing returned by that function. But the fun ()
expression creates a function, which will only evaluate its contents later when it is called. It does not evaluate its contents immediately.
By contrast, the expression (printfn "%d" count; count)
is a block of code with two expressions in it. It is not a function, so it will be immediately evaluated. Its last expression is count
, so the value of the code block (printfn "%d" count; count)
is count
. Since the (printfn "%d" count; count)
block is being evaluated immediately, you can mentally replace it with count
. And so the value of gS
is count
, whereas the value of generateStamp
is a function that will return count
when it's evaluated.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments