2012-04-12 40 views
9

Tôi muốn tạo ra một sản phẩm Cartesian khá lớn nhưng hữu hạn trong Haskell, mà tôi cần sau đó lặp lại (suy nghĩ chức năng phân vùng của mô hình trường trung bình). Điều tự nhiên để làm sử dụng sequence, như thế này:Sản phẩm cartesian lười biếng trong Haskell

l = sequence $ replicate n [0,1,2] 

Thật không may, cho lớn n, điều này không phù hợp trong bộ nhớ và tôi chạy ra khỏi đống ngay sau khi tôi yêu cầu length l ví dụ. Tôi sẽ cần một cách để làm điều tương tự một cách lười biếng. Tôi đã kết thúc "khám phá lại" arithmetics cơ bản-3, như thế này, như thế này,

nextConfig []  = [] 
nextConfig (0:xs) = 1:xs 
nextConfig (1:xs) = 2:xs 
nextConfig (2:xs) = 0:(nextConfig xs) 

ll = take (3^n) $ iterate nextConfig $ replicate n 0 

(hoạt động) nhưng nó cảm thấy như phát minh lại bánh xe, và bên cạnh đó là quá cụ thể. Điều gì sẽ là một cách lười biếng tốt hơn để tạo ra sản phẩm?

+0

Bạn có quan tâm đến thứ tự của các phần tử trong kết quả không? – augustss

+0

Không, miễn là không có sự lặp lại. –

+0

Bạn cần 'n' bao nhiêu? – dave4420

Trả lời

5

Cách nhớ thân thiện hơn thu được bằng cách liên kết theo thứ tự ngược so với trình tự,

foo 0 _ = [[]] 
foo k xs = [h:t | t <- foo (k-1) xs, h <- xs] 

Nó là chậm hơn do chia sẻ ít hơn, nhưng kể từ khi bộ nhớ là vấn đề của bạn, có lẽ nó đủ tốt cho bạn.

+0

Tuyệt! Tôi sẽ phải điều tra thêm tại sao nó hoạt động, nhưng nó chắc chắn. Tôi đã sửa đổi nó thành 'foo (l: ls) = [h: t | t <- foo2 ls, h <- l] '(ai biết nếu tôi sẽ luôn luôn cần một khối lập phương) và nó hoạt động như là tốt. Cảm ơn! –

+0

Tại sao việc hiểu danh sách hiệu quả hơn so với ký hiệu cho các danh sách (được sử dụng trong 'trình tự')? Tôi có thể nhìn thấy từ báo cáo Haskell2010 cả hai người trong số họ desugar để 'concatMap'? – haskelline

+2

@brence: Xem câu trả lời của Duncan Coutts cho câu hỏi reddit này: [Tại sao các lính canh trong danh sách hiểu nhanh hơn trong ký hiệu?] (Http://www.reddit.com/r/haskell/comments/oolyt/why_are_guards_in_the_list_comprehension_faster /) – danr

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