开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜