2009-10-27 10 views
8

मैं आलसी संख्याओं के अनुक्रम का प्रतिनिधित्व करने वाली आलसी सूची कैसे बना सकता हूं? उदाहरण:ओकैमल: आलसी सूचियां

1 2 4 8 16 32 
+1

क्या आपका मतलब आलसी सूचियों, या केवल सामान्य अवधारणा के कुछ विशेष कार्यान्वयन का मतलब है? साथ ही, क्या आपको वास्तव में आलसी _lists_ की आवश्यकता है (जहां मान, एक बार गणना की जाती है, याद की जाती है), या क्या आप वास्तव में केवल एक स्ट्रीम चाहते हैं (जहां मूल्यों को याद नहीं किया जाता है, और इसलिए केवल एक बार पढ़ा जा सकता है)? –

+0

मैं एक स्ट्रीम की तलाश में हूँ। –

उत्तर

9

महान ब्लॉग मताधिकार मन इस विषय पर एक महान लेख है:

http://enfranchisedmind.com/blog/posts/ocaml-lazy-lists-an-introduction/

तुम भी बाहर http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html

जो इस से निपटने के लिए मानक पुस्तकालय है जाँच कर सकते हैं ।

यह सवाल भी बहुत इस सवाल के समान है:

What OCaml libraries are there for lazy list handling?

+0

पहला लिंक अब और काम नहीं करता है, क्या उन्होंने मेजबान को स्थानांतरित किया? – Oleg

+0

@ ओलेग डोमेन की अवधि समाप्त होने की तरह दिखता है। इंटरनेट पर ऐसा जीवन है। यह उत्तर अब लगभग 8 साल पुराना है :) – chollida

+0

बैटरी लाइब्रेरी में अब [तीन अलग-अलग या कम आलसी अनुक्रम प्रकार हैं] (https://github.com/ocaml-batteries-team/batteries-cluded/wiki/ListTypes), विभिन्न गुणों के साथ। – Mars

13

का उपयोग धाराओं:

let f x = Stream.from (fun n -> Some (x * int_of_float (2.0 ** float_of_int n))) 

या

let f x = 
    let next = ref x in 
    Stream.from (fun _ -> let y = !next in next := 2 * y ; Some y) 

एक कस्टम lazy_list प्रकार का उपयोग करना:

type 'a lazy_list = 
    | Nil 
    | Cons of 'a * 'a lazy_list lazy_t 
let rec f x = lazy (Cons (x, f (2*x))) 
1

आप हाथ से यह करना चाहते हैं, मैं कहेंगे आप मुख्य विकल्प के लिए है:,

  • उपयोग एक कस्टम lazy_list प्रकार ephemient की तरह कहा (सिवाय उनके समाधान एक सा टूट है) : (क भाषा है कि यह समर्थन नहीं करता में आलसी मूल्यांकन लागू करने के लिए प्रयोग किया जाता बात की तरह)

    type 'a lazy_list = 
        | Nil 
        | Cons of 'a * 'a lazy_list 
    
    let head = function 
        | Nil -> failwith "Cannot extract head of empty list" 
        | Cons (h, _) -> h 
    
    let tail = function 
        | Nil -> failwith "Cannot extract tail of empty list" 
        | Cons (_, t) -> t 
    
  • thunk का एक प्रकार का उपयोग करें। आप अपनी सूची को unit -> 'a फ़ंक्शन के रूप में परिभाषित करते हैं जो कहता है कि वर्तमान तत्व से अगला तत्व कैसे प्राप्त करें (इसके लिए स्ट्रीम का उपयोग करने की आवश्यकता नहीं है)। उदाहरण के लिए, सभी प्राकृतिक पूर्णांकों की सूची परिभाषित करने के लिए, आप

    let make_lazy_list initial next = 
        let lazy_list current() = 
         let result = !current in 
         current := (next !current); result 
        in lazy_list (ref initial) 
    
    let naturals = make_lazy_list 0 (function i -> i + 1) 
    

    क्या कर सकते हैं अगर आप

    print_int (naturals()); 
    print_int (naturals()); 
    print_int (naturals()) 
    

    आप निम्नलिखित उत्पादन मिल जाएगा कार्य करें:

    0 
    1 
    2 
    
+0

मेरी 'lazy_list' का कौन सा हिस्सा टूटा हुआ है? जब मैंने इसे लिख रहा था तब मैंने इसका परीक्षण नहीं किया था, और मैं ओकैमल की तुलना में हास्केल और एसएमएल से निश्चित रूप से अधिक परिचित हूं, लेकिन मैंने अभी इसका परीक्षण किया और यह ओकैमल 3.11.1 पर काम करता है। स्ट्रीम ज्यादातर इसलिए है क्योंकि ओपी ने धाराओं के लिए पूछे जाने वाले प्रश्न पर एक टिप्पणी जोड़ा। – ephemient

+0

वूप्स, आप सही हैं, मैं वास्तव में * वास्तव में * गलत पढ़ता हूं ... प्लस मैंने स्ट्रीम का उपयोग करने के बारे में टिप्पणी नहीं देखी। अगली बार मैं अपने चश्मा डाल दूंगा: एस। – jdb

3

इसके अलावा, मेरे OCaml Network Application Environment कोर फाउंडेशन में Cf_seq नामक एक आलसी सूची मॉड्यूल है। वास्तव में, मैंने कार्यात्मक डेटा संरचनाओं का एक पूरा पास लिखा था। यह सब 2-खंड बीएसडी लाइसेंस के तहत उपलब्ध है। का आनंद लें।

अद्यतन: कोड का नाम बदलकर "Oni" कर दिया गया है और अब यह बिटबकेट में होस्ट किया गया है। आप इसके लिए GODI पैकेज का भी उपयोग कर सकते हैं।