2012-01-27 11 views
9

Ai đó có thể giải thích hoặc cung cấp một số tài nguyên về cách hoạt động của thành phần chức năng liên quan đến sự lười biếng không?độ lười và thành phần chức năng (haskell, erlang)

Ví dụ: filter (/='W') . map toUpper $ "justaword" hoạt động như thế nào trong Haskell so với đối tác ở erlang không lười?

Trả lời

13

Mỗi lần một ký tự khác được yêu cầu (hoặc thông báo kết thúc), ký tự tiếp theo - nếu có - được ánh xạ thành chữ hoa, được so sánh với 'W', được phân phối nếu không bằng nhau.

filter (/= 'W') . map toUpper $ "justaword" 
~> filter (/= 'W') (toUpper 'j' : map toUpper "ustaword") 
~> filter (/= 'W') ('J' : map toUpper "ustaword") 
~> 'J' : filter (/= 'W') (map toUpper "ustaword") 

Bây giờ ký tự đầu tiên là có sẵn, vì vậy đối với các truy vấn như null hoặc các chức năng như take 1, không có công việc tiếp theo được thực hiện. Nếu nhiều nhân vật được yêu cầu bởi người tiêu dùng, họ sẽ được sản xuất từng cái một cho đến khi kết thúc chuỗi.

Ví dụ:

Prelude Data.Char> take 10 . filter (/= 'W') . map toUpper $ repeat 't' 
"TTTTTTTTTT" 

repeat tạo ra một danh sách vô hạn, nhưng miễn là chỉ là một phần hữu hạn được tiêu thụ, tính toán kết thúc trong thời gian hữu hạn. Tuy nhiên, take 10 . filter (/= 'W') . map toUpper $ repeat 'w' sẽ không chấm dứt, vì không có ký tự nào được sản xuất vượt qua số filter để đến được số take 10.

+0

Cảm ơn bạn đã thực hiện một cách tuyệt vời :) Có thể viết mã này bằng ngôn ngữ nghiêm ngặt (không mô phỏng sự lười biếng) không? Hoặc trong một languege nghiêm ngặt danh sách sẽ được đi qua hai lần, một lần cho bản đồ và một lần cho bộ lọc, bắt đầu từ beginnig? – Adi

+1

@Adi: có, sẽ có hai danh sách traversals. bản đồ sẽ trả về một danh sách trung gian mới, được chuyển tới bộ lọc, sẽ vượt qua và trả về một danh sách khác – newacct

+5

Trong một ngôn ngữ nghiêm ngặt (mong muốn), người ta sẽ phải mô phỏng sự lười biếng để có được hành vi tương tự. Một số ngôn ngữ làm cho dễ dàng hơn những người khác, tôi muốn làm điều đó hơn trong erlang hoặc F # hơn trong C (và mặc dù tôi biết C, nhưng hầu như không có bất kỳ erlang hoặc F # :). Cho dù có hai traversals hoặc một trong một ngôn ngữ mong muốn phụ thuộc vào trình biên dịch. Về nguyên tắc, bộ lọc và bản đồ có thể được hợp nhất, nhưng nói chung trình biên dịch sẽ cần phải chứng minh độ tinh khiết của hàm được ánh xạ và vị từ bộ lọc để có thể thực hiện điều đó. Vì vậy, tôi mong đợi hai traversals trong hầu hết các trường hợp, bằng chứng là khó khăn. –