2009-10-27 45 views
8

Làm cách nào để tạo danh sách lười biếng đại diện cho một chuỗi các số có gấp đôi? Ví dụ:Ocaml: Danh sách lười biếng

1 2 4 8 16 32 
+1

Bạn có nghĩa là một số triển khai cụ thể các danh sách lười biếng hay chỉ là khái niệm chung? Ngoài ra, bạn có thực sự cần _lists_ lười biếng (nơi các giá trị, khi được tính toán, được ghi nhớ) hay bạn thực sự chỉ muốn một luồng (trong đó các giá trị không được ghi nhớ và do đó chỉ có thể đọc một lần)? –

+0

Tôi đang tìm một luồng. –

Trả lời

9

vĩ đại tâm viết blog enfranchised có một bài viết tuyệt vời về chủ đề này:

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

Bạn cũng có thể kiểm tra http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html

đó là thư viện chuẩn để đối phó với điều này .

Câu hỏi này cũng rất giống với câu hỏi này:

What OCaml libraries are there for lazy list handling?

+0

Liên kết đầu tiên không hoạt động nữa, họ có di chuyển máy chủ không? – Oleg

+0

@Oleg trông giống như miền đã hết hạn. Đó là cuộc sống trên internet. Câu trả lời này đã gần 8 tuổi rồi :) – chollida

+0

Thư viện pin giờ đây có [ba loại trình tự lười biếng khác nhau ít hơn] (https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes), với các thuộc tính khác nhau. – Mars

13

Sử dụng dòng:

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

hoặc

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

Sử dụng một kiểu tùy chỉnh 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

Nếu bạn muốn làm điều đó bằng tay, tôi muốn nói rằng bạn phải lựa chọn chính:

  • Sử dụng một kiểu tùy chỉnh lazy_list, như ephemient nói (trừ giải pháp của ông là một chút bị hỏng) :

    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 
    
  • Sử dụng một loại thunk (như điều được sử dụng để thực hiện đánh giá lười biếng bằng ngôn ngữ không hỗ trợ). Bạn xác định danh sách của mình dưới dạng hàm unit -> 'a cho biết cách lấy phần tử tiếp theo từ phần tử hiện tại (không cần sử dụng luồng cho điều đó). Ví dụ, để xác định danh sách của tất cả các số nguyên tự nhiên, bạn có thể làm

    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) 
    

    Các nếu bạn làm

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

    bạn sẽ nhận được kết quả như sau:

    0 
    1 
    2 
    
+0

Phần nào của 'lazy_list' của tôi bị hỏng? Tôi đã không kiểm tra nó khi tôi đang viết nó, và tôi chắc chắn quen thuộc hơn với Haskell và SML hơn OCaml, nhưng tôi đã thử nghiệm nó ngay bây giờ và nó hoạt động, trên OCaml 3.11.1. Các luồng chủ yếu là do OP đã thêm nhận xét cho câu hỏi yêu cầu luồng. – ephemient

+0

Rất tiếc, bạn nói đúng, tôi thực sự * thực sự * hiểu sai ... Cộng với tôi không thấy nhận xét về việc sử dụng luồng. Lần tới tôi sẽ đeo kính vào: s. – jdb

3

Ngoài ra, có một mô-đun danh sách lười biếng được gọi là Cf_seq trong Tổ chức lõi của tôi OCaml Network Application Environment. Trong thực tế, tôi đã viết một passle toàn bộ các cấu trúc dữ liệu chức năng. Tất cả đều có sẵn theo giấy phép BSD 2 điều khoản. Thưởng thức.

Cập nhật: mã đã được đổi tên thành "Oni" và hiện được lưu trữ tại BitBucket. Bạn cũng có thể sử dụng gói GODI cho nó.

Các vấn đề liên quan