2012-09-14 27 views
17

Lợi ích hiệu suất của việc sử dụng ~ (kết hợp mẫu lười) trong phân vùng Data.List là gì. Ví dụ về sự phù hợp với mô hình lười biếng gợi ý rằng nó rất hữu ích khi các giá trị bên trong hàm tạo tuple không bao giờ được sử dụng (f (x, y) = 1). Trong phân vùng (chọn, bên dưới), danh sách ts, fs luôn được sử dụng (nếu vị từ p được áp dụng cho x là True, hay không). Tôi chắc chắn đây là một quyết định rất tốt để sử dụng ~, nhưng điểm là gì? Tại sao không phù hợp với mô hình nghiêm ngặt?Đối sánh mẫu phù hợp trong dữ liệu.LIST

partition    :: (a -> Bool) -> [a] -> ([a],[a]) 
{-# INLINE partition #-} 
partition p xs = foldr (select p) ([],[]) xs 

select :: (a -> Bool) -> a -> ([a], [a]) -> ([a], [a]) 
select p x ~(ts,fs) | p x  = (x:ts,fs) 
        | otherwise = (ts, x:fs) 

(Lưu ý: Tôi đã nhìn here nó không trả lời câu hỏi ở trên!)

+0

cf. http://en.wikipedia.org/wiki/Tail_call#Tail_recursion_modulo_cons –

Trả lời

17

Vấn đề là với kiểu kết hợp chặt chẽ, lắp ráp các kết quả chỉ có thể bắt đầu khi kết thúc danh sách được phân chia đã đạt được, đặc biệt, partition sẽ không hoạt động ở tất cả các danh sách vô hạn.

Với khớp mẫu phù hợp, đối số phải được đánh giá thành WHNF. Điều đó có nghĩa là toàn bộ foldr của đuôi phải hoàn thành trước khi nó được quyết định liệu x được đặt trong thành phần thứ nhất hay thứ hai.

select p x (foldr (select p) ([],[]) (y:z:ws)) 
~> select p x (select p y (select p z (foldr (select p) ([],[]) ws))) 

Với một mô hình phù hợp lười biếng, một cặp được thi công ngay, với x là yếu tố đầu tiên của các thành phần thích hợp, và phần còn lại của hai danh sách được đánh giá sau, khi cần thiết.

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