2012-03-18 16 views
5

Lazy.lazy_from_val के दस्तावेज़ में कहा गया है इस समारोह विशेष मामलों के लिए है:OCaml's Lazy.lazy_from_val का उद्देश्य क्या है?

val lazy_from_val : 'a -> 'a t 
    lazy_from_val v returns an already-forced suspension of v This is for special purposes only and should not be confused with lazy (v). 

कौन सा मामलों में वे के बारे में बात कर रहे हैं?

अगर मैं की तरह एक मूल्य से निलंबित कर दिया गणना की एक जोड़ी बनाने के लिए:

let l1 = lazy 123 
let l2 = Lazy.lazy_from_val 123 

इन दोनों के बीच क्या अंतर है? क्योंकि Lazy.lazy_is_val l1 और Lazy.lazy_is_val l2 दोनों सत्य कह रहे हैं कि मान पहले से ही मजबूर है!

उत्तर

7

विशेष उद्देश्य होगा। आप अपने मूल्य के एक (मजबूर) आलसी संस्करण में पहले से गणना किए गए मान को चालू करने के लिए lazy_from_val का उपयोग कर सकते हैं।

let f lazyint = 
    Lazy.force lazyint + 42 

let li = lazy 4;; 

# f li;; 
- : int = 46 
# f 14;; 
    ^^ 
Error: This expression has type int but an expression was expected of type 
     int Lazy.t = int lazy_t 
# f (Lazy.lazy_from_val 14);; 
- : int = 56 

इस (काल्पनिक) उदाहरण में, आप एक साधारण पूर्णांक मान के साथ f कॉल करने के लिए (14 इस उदाहरण में,) इच्छा हो सकती है। आप इसे कर सकते हैं, लेकिन इसे काम करने के लिए आपको Lazy.lazy_from_val का उपयोग करने की आवश्यकता है।

मुख्य अंतर यह है कि lazy प्रकार 'a की अभिव्यक्ति प्रकार 'a lazy_t की (एक बंद संक्षेप में,) लेता है और एक को निलंबित कर दिया गणना बनाता है। Lazy.lazy_from_val'a टाइप का एक पूर्व-गणना मूल्य लेता है और इसे 'a lazy_t प्रकार के (पूर्व-मजबूर) मान में परिवर्तित करता है। अगर अभिव्यक्ति के दुष्प्रभाव होते हैं, तो दोनों के बीच का अंतर देखा जा सकता है।

# let p() = print_string "here\n"; 3 ;; 
val p : unit -> int = <fun> 
# let l1 = lazy (p());; 
val l1 : int lazy_t = <lazy> 
# let l2 = Lazy.lazy_from_val (p());; 
here 
val l2 : int Lazy.t = lazy 3 
# f l1;; 
here 
- : int = 45 
# f l2;; 
- : int = 45 
# 

आप स्पष्ट बंदियों और संदर्भों का उपयोग करके सीधे आलसी संचालन को लागू कर सकते हैं। चूंकि मैथियस बेनकार्ड बताते हैं, ओकैमल की आलसी तंत्र विशेष वाक्यविन्यास का उपयोग करता है ताकि इसे काम करने में कम बोझिल बना दिया जा सके। आईई, lazy एक ओकैमल कीवर्ड है, फ़ंक्शन नहीं।

+0

स्पष्टीकरण के लिए धन्यवाद! – Ricardo

+1

"ओकैमल की आलसी तंत्र विशेष वाक्यविन्यास का उपयोग करता है" ... और विशेष जीसी विशेषताओं को मजबूर मूल्यों के लिए, बेकार बनने के लिए, संकेतक को हटाने के लिए। –

+0

वास्तव में जानना अच्छा है, धन्यवाद! (क्या इसके लिए कोई अच्छा रेफरी है?) –

2

lazy_from_val वाक्यविन्यास के बजाय एक कार्य है। इस प्रकार, यदि आप एक आलसी मूल्य की जरूरत है, लेकिन आप कभी कभी एक पहले से ही गणना की (गैर आलसी) मूल्य

# let id = fun x -> x;; 
val id : 'a -> 'a = <fun> 
# Lazy.lazy_is_val (lazy (id 123));; 
- : bool = false 
# Lazy.lazy_is_val (Lazy.lazy_from_val (id 123));; 
- : bool = true