2012-02-08 15 views
16

Tôi không thể quấn quanh đầu sự khác biệt giữa trình tự và LazyList. Cả hai đều lười biếng và có khả năng vô hạn. Trong khi seq<'T>IEnumerable<'T> từ .NET framework, LazyList được bao gồm trong F# PowerPack. Trong thực tế, tôi gặp các chuỗi nhiều hơn thường xuyên hơn LazyList s.Trình tự so với LazyList

Sự khác biệt của chúng về hiệu suất, mức sử dụng, khả năng đọc, v.v ... là gì? Lý do cho danh tiếng xấu như vậy của LazyList là gì so với seq?

Trả lời

31

LazyList chỉ tính mỗi phần tử một lần bất kể số lần danh sách được duyệt qua. Bằng cách này, nó gần với một chuỗi được trả về từ Seq.cache (chứ không phải là một chuỗi điển hình). Tuy nhiên, khác với bộ nhớ đệm, LazyList hoạt động chính xác như danh sách: nó sử dụng cấu trúc danh sách dưới mui xe và hỗ trợ khớp mẫu. Vì vậy, bạn có thể nói: sử dụng LazyList thay vì seq khi bạn cần danh sách ngữ nghĩa và bộ nhớ đệm (ngoài sự lười biếng).

Về cả hai là vô hạn, sử dụng bộ nhớ của seq là không đổi trong khi LazyList là tuyến tính.

Những docs có thể đáng đọc.

+0

+1, tuyệt, tôi không biết về phần bộ nhớ đệm. Bạn có thể đưa ra một ví dụ đòi hỏi cả ngữ nghĩa lười biếng và danh sách? – pad

+0

Traversing một chuỗi trong khi đồng thời truy cập nhiều phần tử có thể được thực hiện với 'seq', nhưng nó sạch hơn nhiều bằng cách sử dụng' LazyList' + pattern matching. – Daniel

+0

Xem ví dụ http://stackoverflow.com/questions/3484315/how-to-merge-sorted-sequences-in-f và http://stackoverflow.com/questions/1306140/f-why-is-using-a-sequence- so-nhiều-chậm-hơn-sử dụng-a-danh sách-trong-ví dụ này/1306267 # 1306267 – Brian

19

Ngoài câu trả lời của Daniel, tôi nghĩ sự khác biệt thực tế chính là cách bạn xử lý các cấu trúc LazyList hoặc seq (hoặc tính toán).

  • Nếu bạn muốn xử lý LazyList, bạn thường sẽ viết một hàm đệ quy sử dụng kết hợp mô hình (khá giống với chế biến F # danh sách bình thường)

  • Nếu bạn muốn xử lý seq, bạn có thể sử dụng được xây dựng trong chức năng hoặc bạn phải viết mã bắt buộc gọi GetEnumerator và sau đó sử dụng trả về điều tra trong một vòng lặp (có thể được viết như một hàm đệ quy, nhưng nó sẽ làm biến đổi điều tra). Bạn không thể sử dụng kiểu đầu/đuôi thông thường (sử dụng Seq.tailSeq.head), vì điều đó cực kỳ không hiệu quả - vì seq không giữ nguyên tố được đánh giá và kết quả của Seq.head cần phải lặp lại từ đầu.

Về uy tín của seqLazyList, tôi nghĩ rằng F # thư viện thiết kế một cách tiếp cận thực dụng - kể từ seq thực sự là NET IEnumerable, nó là khá thuận tiện cho việc lập trình .NET (và nó cũng là tốt đẹp bởi vì bạn có thể xem các bộ sưu tập khác là seq). Danh sách lười biếng không phải là danh sách F # thường xuyên và quá bình thường và seq là đủ trong hầu hết các trường hợp.

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