F # - нужна помощь, чтобы кто-то объяснил Lazy Functions и почему я получаю определенный результат - PullRequest
1 голос
/ 03 июля 2010

У меня вопрос, почему я получаю определенные результаты в F #. У меня есть следующий код ...

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

Мой вывод выглядит следующим образом ...

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

Чего я не могу понять, так это ... Почему printfn активного привет-мира показывается перед ленивым привет-словом? Я ожидал, что «Ленивый мир приветствия» будет показан раньше, чем «Активный привет мир»?

Если кто-нибудь может помочь объяснить это, то будет очень признателен.

Ответы [ 2 ]

6 голосов
/ 03 июля 2010

Вот мое аннотированное описание

// 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.
1 голос
/ 03 июля 2010

Ну, я не большой F # человек, но с ленивыми шаблонами он настроен так, что они ничего не делают, пока не получат запрос.Поэтому, когда вы завернете это в ленивый, он не запустится, пока вы его не используете.Но так как вы не использовали это для активного, он выполнял функцию, как только она была назначена.

Это всего лишь предположение, поскольку я не парень F #.

Здесьэто статья, которая объясняет это также.http://weblogs.asp.net/podwysocki/archive/2008/03/21/adventures-in-f-f-101-part-6-lazy-evaluation.aspx

Извините, забыл прикрепить ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...