2010-04-02 33 views
5

Tôi hiểu rằng bộ lọc Haskell là một hàm bậc cao (có nghĩa là một hàm lấy hàm khác làm tham số) đi qua danh sách kiểm tra phần tử nào đáp ứng điều kiện boolean nhất định.Hiểu bộ lọc của Haskell

Tôi hoàn toàn không hiểu định nghĩa của nó:

filter:: (a->Bool)->[a]->[a] 
filter p [] = [] 
filter p (x:y) | p x = x:filter p y 
       | otherwise = filter p y 

Tôi hiểu rằng nếu tôi vượt qua một danh sách trống với chức năng, nó chỉ sẽ trả về một danh sách trống, nhưng làm thế nào để tôi đọc hai dòng cuối cùng ?

+0

@Justice: Tôi tự hỏi, nếu định dạng lại hợp lệ.Có lẽ OP đã thực sự bối rối bởi cách bố trí kỳ lạ? – kennytm

Trả lời

11

Sử dụng guards nếu bạn đến từ một ngôn ngữ có cú pháp kiểu C hơi giống với cấu trúc switch.

Mẫu cuối cùng đọc: Nếu hàm p đánh giá đúng với đối số x thì hãy trả về đầu danh sách và đuôi được lọc của danh sách. Nếu không, chỉ cần trả về đuôi được lọc của danh sách.

Bạn cũng có thể viết lại nó như vậy:

filter p (x:y) = if ( p x) then 
        x:filter p y 
       else 
        filter p y 
+3

Ngoài ra 'nếu không' được định nghĩa là' True' trong phần mở đầu. –

7

Xem xét description of filter in the docs:

filter, áp dụng cho một vị và một danh sách, trả về danh sách những nhân tố này đáp ứng các vị ngữ; tức,

filter p xs = [x | x <- xs, p x] 

Để giải thích cho ai đó không hiểu comprehensions danh sách, bạn có thể nói filter có ba trường hợp:

  1. (trường hợp đơn giản) khi danh sách được được lọc trống, kết quả cũng trống rỗng
  2. khi người đứng đầu danh sách được lọc đáp ứng vị từ, đó là một phần của kết quả
  3. nếu không, bỏ qua phần đầu và lọc phần còn lại của danh sách

Những trường hợp này tương ứng với một trong ba dòng cuối cùng của định nghĩa trong câu hỏi của bạn.

chạm nhỏ có thể làm cho các định nghĩa thành ngữ hơn và do đó dễ dàng hơn để đọc:

filter _ []  = [] 
filter p (x:xs) 
    | p x   = x : filter p xs 
    | otherwise =  filter p xs 

Đối với một danh sách trống, vị từ có thể được bất cứ điều gì ở tất cả, và gạch dưới cho thấy một cách rõ ràng rằng nó không quan trọng trong trường hợp đó.

Thay vì phù hợp với (x:y), sử dụng (x:xs) -think: "cũ và người yêu cũ" -emphasizes rằng bạn đang tách một danh sách vào đầu của nó (kiểu a) và đuôi (loại [a], tức, danh sách các a).

Cuối cùng, xếp các cuộc gọi đệ quy lên filter dễ dàng cho phép người đọc thấy rằng trường hợp thứ hai bỏ qua x.

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