2012-01-18 45 views

Trả lời

6

Nếu bạn thấy mình lập trình liên tục thành mẫu, điều cần làm là viết hàm bậc cao hơn để đóng gói mẫu đó. Bạn có thể sử dụng cơ thể bạn có, nhưng để được hoàn toàn tự tin rằng mã của bạn không phân bổ, tôi sẽ khuyên bạn nên sử dụng foldl và ứng dụng nghiêm ngặt của một nhà điều hành increment:

numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n 
numberSatisfying p = foldl (\n x -> if p x then (+1) $! n else n) 0 

Tôi đã sử dụng QuickCheck để khẳng định điều này mã tương đương với mã ban đầu của bạn. (Và có, nó là khá mát mẻ mà QuickCheck sẽ kiểm tra với các vị từ ngẫu nhiên.)

+3

Tại sao không 'foldl''? –

+0

@trinithis không có trong Prelude ... –

8

Primo

guard someGuard 
return() 

là không cần thiết, guard đã trả () nếu điều kiện là đúng. Sau đó, tôi giả sử someGuard thực sự phụ thuộc vào x, nếu không nó sẽ là if someGuard then length someList else 0. Cách thông thường để viết là

someFunc foo = filter (\x -> someGuard) someList 

nếu tình huống thực sự đơn giản như ví dụ của bạn. Đối với các tình huống phức tạp hơn, việc sử dụng một trong các kiểu mẫu của bạn là cách trực tiếp nhất. Tôi tìm thấy ký hiệu thích hợp hơn nếu mọi thứ trở nên phức tạp.

+0

+1 Có, 'someList' phụ thuộc vào' foo' và 'someGuard' phụ thuộc vào cả' foo' và 'x'. Biểu thức lọc có lẽ là cách đơn giản nhất để nắm bắt điều đó. –

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