Come posso creare una lista pigra che rappresenta una sequenza di numeri raddoppiati? Esempio:Ocaml: Lazy Lists
1 2 4 8 16 32
Come posso creare una lista pigra che rappresenta una sequenza di numeri raddoppiati? Esempio:Ocaml: Lazy Lists
1 2 4 8 16 32
La grande mente blog affrancato ha un grande articolo su questo argomento:
http://enfranchisedmind.com/blog/posts/ocaml-lazy-lists-an-introduction/
Si può anche verificare http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html
che è la libreria standard per affrontare questo .
Questa domanda è molto simile a questa domanda:
Il primo collegamento non funziona più, hanno spostato l'host? – Oleg
@Oleg si presenta come il dominio scaduto. Tale è la vita su internet. Questa risposta ha quasi 8 anni :) – chollida
La libreria Batterie ora ha [tre diversi tipi di sequenza più o meno pigri] (https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes), con diverse proprietà. – Mars
Uso torrenti:
let f x = Stream.from (fun n -> Some (x * int_of_float (2.0 ** float_of_int n)))
o
let f x =
let next = ref x in
Stream.from (fun _ -> let y = !next in next := 2 * y ; Some y)
Utilizzando un tipo personalizzato 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)))
Se si vuole farlo a mano, direi che devi opzioni principali:
Utilizzare un tipo personalizzato lazy_list
, come ephemient detto (eccetto la sua soluzione è un po 'rotto) :
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
utilizzare una specie di tonfo (come la cosa utilizzato per implementare la valutazione pigra in una lingua che non lo supporta). Definisci il tuo elenco come una funzione unit -> 'a
che dice come ottenere l'elemento successivo da quello corrente (non è necessario utilizzare flussi per questo). Ad esempio, per definire l'elenco di tutti i numeri interi naturali, si può fare
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)
Il se lo fai
print_int (naturals());
print_int (naturals());
print_int (naturals())
si otterrà il seguente output:
0
1
2
Quale parte del mio 'lazy_list' è rotta? Non l'ho provato quando lo stavo scrivendo, e ho sicuramente più familiarità con Haskell e SML rispetto a OCaml, ma l'ho testato proprio ora e funziona, su OCaml 3.11.1. Gli stream sono principalmente perché OP ha aggiunto un commento alla domanda che chiede flussi. – ephemient
Woops, hai ragione, ho davvero * veramente * letto male ... Inoltre non ho visto il commento sull'utilizzo degli stream. La prossima volta mi metterò gli occhiali: s. – jdb
Inoltre, esiste un modulo elenco pigro chiamato Cf_seq
nella mia Fondazione core OCaml Network Application Environment. In effetti, ho scritto un'intera passerella di strutture dati funzionali. È tutto disponibile con una licenza BSD a 2 clausole. Godere.
Aggiornamento: il codice è stato rinominato "Oni" ed è ora ospitato su BitBucket. Puoi anche usare il pacchetto GODI per questo.
Intendi qualche particolare implementazione di liste pigre, o solo il concetto generale? Inoltre, hai effettivamente bisogno di _lists_ pigri (dove i valori, una volta calcolati, sono memoizzati), o vuoi davvero un flusso (dove i valori non sono memoizzati e che possono quindi essere letti solo una volta)? –
Sto cercando un flusso. –