2011-08-04 2 views
1

Je commence juste F # et je n'ai pas vraiment fait de programmation fonctionnelle depuis mes cours de programmation il y a 15 ans (exception faite de C# "moderne").F # noob aider à comprendre Lazy and Value

Je regarde ce F # snippet en utilisant 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 

La sortie qu'il produit est:

Lazy<Int32> 
    Value is not created. 
    IsValueCreated False 
    Value 16 

16 

Je comprends le mot-clé paresseux pour retarder l'évaluation jusqu'à ce que nécessaire, même que C# exécution retardée.

Quelle est la signification de: "La valeur n'est pas créée" ici?

+0

Quelle est la mise en œuvre de «Dump»? – ildjarn

+0

Bonjour Gabriel, Personnellement, je suis un utilisateur lourd LINQPad, ayant à la fois ma propre licence et a réussi à obtenir mon entreprise pour acheter 5 autres pour mes collègues et comme Tomas déjà mentionné, F # Interactive est actuellement une meilleure option. –

+0

merci pour le conseil - ouais j'aime linqpad aussi mais je vais aller avec la suggestion pour F # –

Répondre

3

Si vous utilisez le mot-clé lazy pour construire une valeur paresseuse (comme dans votre fonction lazyPlusOne), le résultat est une valeur de type Lazy<int>. Cela représente une valeur de type int qui est évaluée uniquement lorsqu'elle est réellement nécessaire.

Je suppose que la fonction Dump essaie d'imprimer la valeur, y compris toutes ses propriétés - quand il commence l'impression, la valeur est évaluée, donc ToString imprime méthode Value is not created. Ensuite, il effectue une itération sur les autres propriétés et quand il accède Value, la valeur paresseuse est évalué (parce que sa valeur est maintenant nécessaire). Après évaluation, la propriété renvoie 16, qui est ensuite imprimée.

Vous pouvez remplacer Dump avec une fonction d'impression F # -Friendly (ou tout simplement utiliser F # Interactive, ce qui est une façon très pratique pour jouer avec F # dans Visual Studio avec l'IntelliSense habituelle, erreur de vérification des antécédents ETEC.)

F # fonction d'impression conviviale comme printfn "%A" n'a pas accès à la propriété Value, donc il n'évalue pas accidentellement la valeur. Voici un extrait de 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 
+0

merci - je pourrais avoir descendu un mauvais chemin de "intuition" sinon pour votre réponse –

0

Au 'Dump e', 'lazyPlusOne 15' n'a pas été évalué. Le 'let e = lazyPlusOne 15' ne nécessite pas l'évaluation de 'lazyPlusOne 15'. Nous n'avons pas encore besoin de savoir à quoi correspond l'e. Le vidage déclenche l'évaluation et est sémantiquement différent que la vidage de la valeur après l'évaluation.

Questions connexes