2009-10-27 5 views
8

Wie kann ich eine faule Liste erstellen, die eine Folge von Doppelnummern darstellt? Beispiel:Ocaml: Lazy Lists

1 2 4 8 16 32 
+1

Meinst du irgendeine besondere Implementierung von faulen Listen oder nur das allgemeine Konzept? Brauchen Sie tatsächlich faule _lists_ (wo einmal berechnete Werte gespeichert werden), oder wollen Sie wirklich nur einen Stream (wo Werte nicht memoisiert sind und daher nur einmal gelesen werden können)? –

+0

Ich suche nach einem Stream. –

Antwort

9

Der große Blog enfranchised Geist hat einen großen Beitrag zu diesem Thema:

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

Sie auch aus http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html

überprüfen, die die Standard-Bibliothek ist damit für den Umgang .

Diese Frage ist auch sehr ähnlich zu dieser Frage:

What OCaml libraries are there for lazy list handling?

+0

Der erste Link funktioniert nicht mehr, haben sie den Host verschoben? – Oleg

+0

@Oleg sieht aus wie die Domain abgelaufen ist. So ist das Leben im Internet. Diese Antwort ist jetzt fast 8 Jahre alt. – chollida

+0

Die Batteries Bibliothek hat jetzt [drei verschiedene mehr oder weniger Lazy Sequence Typen] (https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes), mit verschiedenen Eigenschaften. – Mars

13

Mit Streams:

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

oder

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

einen benutzerdefinierten lazy_list Typen verwenden:

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

Wenn Sie es von Hand machen wollen, würde ich sagen Sie zur Haupt Möglichkeiten:

  • Verwenden Sie eine benutzerdefinierte lazy_list Art, wie ephemient sagte (mit Ausnahme seiner Lösung ein bisschen gebrochen ist) :

    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 
    
  • eine Art Thunk verwenden (wie die Sache verwendet lazy evaluation in einer Sprache zu implementieren, die nicht unterstützt wird). Sie definieren Ihre Liste als eine Funktion unit -> 'a, die sagt, wie man das nächste Element von dem aktuellen Element erhält (keine Notwendigkeit, Ströme dafür zu verwenden). Um zum Beispiel die Liste aller natürlichen Zahlen zu definieren, können Sie

    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) 
    

    Das tun, wenn Sie

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

    tun, werden Sie die folgende Ausgabe:

    0 
    1 
    2 
    
+0

Welcher Teil meiner 'faul_list' ist defekt? Ich habe es nicht getestet, als ich es geschrieben habe, und ich bin definitiv besser mit Haskell und SML vertraut als OCaml, aber ich habe es gerade getestet und es funktioniert auf OCaml 3.11.1. Streams gibt es hauptsächlich, weil OP der Frage, die nach Streams fragt, einen Kommentar hinzugefügt hat. – ephemient

+0

Woops, du hast Recht, ich habe wirklich * wirklich * das falsch gelesen ... Außerdem habe ich den Kommentar zur Verwendung von Streams nicht gesehen. Nächstes Mal werde ich meine Brille anziehen: s. – jdb

3

Außerdem gibt es ein Faul List-Modul namens Cf_seq in meinem OCaml Network Application Environment Core Foundation. Tatsächlich habe ich eine ganze Reihe funktionaler Datenstrukturen geschrieben. Es ist alles unter einer 2-Klausel-BSD-Lizenz verfügbar. Genießen.

aktualisieren: Der Code wird umbenannt „Oni“ und jetzt ist es an BitBucket gehostet. Sie können auch das Paket GODI dafür verwenden.