开发者

F# - need help for someone to explain Lazy Functions and why I am getting a certain result

I have a question on why I am getting certain results in F#. I have the following code...

let lHelloWorld = lazy(printfn "Lazy Hello World"; 30+30)
let aHelloWorld = (printfn "Active Hello World"; 30+30)

printfn "lazy value is %d"  lHelloWorld.Value 
printfn "lazy value is %d"  lHelloWorld.Value
printfn "active value is %d"  aHelloWorld
printfn "active value is %d"  aHelloWorld

My output is as follows...

Active Hello World
Lazy Hello World
lazy value is 60
lazy value is 60
active value is 60
active value is 60

What I can't understand is this... Why is active hello world's printfn being shown before lazy hello word? I would have expected "Lazy Hello World" to have been shown before "Active Hello World"?

If anyone can 开发者_如何学Gohelp explain this it would be much appreciated.


Here's my annotated description

// Here we go...
let lHelloWorld = lazy(printfn "Lazy Hello World"; 30+30) 
// Ok, we defined a value called lHelloWorld.  The right hand side is 
// a lazy(...), so we don't evaluate the ..., we just store it in a
// System.Lazy object and assign that value to lHelloWorld.

let aHelloWorld = (printfn "Active Hello World"; 30+30) 
// Ok, we're defining a value called aHelloWorld.  The right hand side is
// a normal expression, so we evaluate it it right now.  Which means we
// print "Active Hello World", and then compute 30+30=60, and assign the
// final result (60) to aHelloWorld.

// Note that neither of the previous two entities are functions.


// Now we have some effects:
printfn "lazy value is %d"  lHelloWorld.Value  
// Calling .Value on an object of type System.Lazy will either
//  - force the value if it has not yet been evaluated, or
//  - return the cached value if it was previously evaluated
// Here we have not yet evaluated it, so we force the evaluation, 
// which prints "Lazy Hello World" and then computes 30+30=60, and then
// stores the final 60 value in the lHelloWorld's cache.  Having evaluated 
// the arguments to the printfn on this line of code, we can now call that
// printfn, which prints "lazy value is 60".

printfn "lazy value is %d"  lHelloWorld.Value 
// This time, calling .Value just fetches the already-computed cached value,
// 60, and so this just prints "lazy value is 60".

printfn "active value is %d"  aHelloWorld 
// aHelloWorld has type 'int'.  Its value is 60.  This is trivial, 
// it prints "active value is 60".
printfn "active value is %d"  aHelloWorld 
// Ditto.


Well I am not a big F# person but with lazy patterns it is set so they don't do anything until they are request. So when you wrap that in lazy it won't run until you actually use it. But since you didn't use that for the active one it performed the function as soon as it was assigned.

This is just a guess though as I am not a F# guy.

Here is an article that explains it as well. http://weblogs.asp.net/podwysocki/archive/2008/03/21/adventures-in-f-f-101-part-6-lazy-evaluation.aspx

Sorry forgot to attach the link.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜