F# noob help understanding Lazy and Value
I'm just beginning F# and haven't really done functional p开发者_高级运维rogramming since my programming languages class 15 years ago (exception being "modern" C#).
I'm looking at this F# snippet using LINQPad 4:
let add x y = x + y
let lazyPlusOne x = lazy add x 1
let e = lazyPlusOne 15
Dump e
let plusOne x = add x 1
let f = plusOne 15
Dump f
The output it produces is:
Lazy<Int32>
Value is not created.
IsValueCreated False
Value 16
16
I understand the lazy keyword to delay evaluation until needed, same as C# delayed execution.
What is the meaning of: "Value is not created" here?
If you use lazy
keyword to construct a lazy value (as in your lazyPlusOne
function), then the result is a value of type Lazy<int>
. This represents a value of type int
that is evaluated only when it is actually needed.
I assume that Dump
function tries to print the value including all its properties - when it starts printing, the value is not evaluated, so ToString
method prints Value is not created.
Then it iterates over other properties and when it accesses Value
, the lazy value is evaluated (because its value is now needed). After evaluation, the property returns 16, which is then printed.
You can replace Dump
with an F#-friendly printing function (or just use F# Interactive, which is extremely convenient way to play with F# inside Visual Studio with the usual IntelliSense, background error checking etec.)
F#-friendly printing function like printfn "%A"
doesn't access the Value
property, so it doesn't accidentally evaluate the value. Here is a snippet from F# Interactive:
> let a = lazy (1 + 2);;
val a : Lazy<int> = Value is not created. // Creates lazy value that's not evaluated
> a;;
val it : Lazy<int> = Value is not created. // Still not evaluated!
> a.Value;; // Now, the lazy value needs to be evaluated (to get the Value)
val it : int = 3
> a;; // After evaluation, the value stays cached
val it : Lazy<int> = 3
As of 'Dump e', 'lazyPlusOne 15' has not been evaluated. The 'let e = lazyPlusOne 15' does not require the evaluation of 'lazyPlusOne 15'. We don't yet need to know what e evaluates to yet. The dump is triggering the evaluation and that is semantically different that just dumping the value after the evaluation.
精彩评论