2010-10-04 42 views
33

Tôi vừa mới bắt đầu tìm hiểu Haskell không quan tâm. Tôi theo dõi learnyouahaskell.com.null thay vì ==

Có Tôi thấy điều này:

null kiểm tra nếu một danh sách rỗng. Nếu nó là, nó trả về True, nếu không thì sẽ trả lại False. Sử dụng chức năng này thay vì xs == [] (nếu bạn có một danh sách gọi xs)

Tại sao vậy? Tại sao chúng ta nên sử dụng null thay vì == khi cả hai sản xuất cùng một kết quả?

Cảm ơn.

+0

Câu hỏi tuyệt vời BTW. Ý nghĩ vẫn chưa vượt qua tâm trí tôi. (Vẫn học Haskell quá) –

Trả lời

66

So sánh danh sách với == đòi hỏi yếu tố để có thể so sánh (được biểu thị là Eq a).

Prelude> :t (==[]) 
(==[]) :: (Eq a) => [a] -> Bool 

Ví dụ: [sin] == [] sẽ không hoạt động vì bạn không thể so sánh các chức năng. Nó có thể có vẻ ngu ngốc, nhưng hệ thống kiểu phải đánh giá loại biểu thức mà không nhìn vào giá trị của nó.

Séc thay thế sẽ là length xs == 0, điều này không yêu cầu sự bình đẳng nhưng sẽ không dừng nếu danh sách của bạn là vô hạn (hãy thử length [1..] == 0). Đó là lý do tại sao có một chức năng chuyên dụng.

null [] = True 
null _ = False 

Prelude> :t null 
null :: [a] -> Bool  -- Notice lack of (Eq a). 
10

Theo ý kiến ​​của tôi, null myList đọc tự nhiên hơn myList == [].

Nhưng raison d'être cho null là nó có thể được sử dụng làm chức năng. Ví dụ, đây là một chức năng mà phải mất một danh sách liệt kê, và trả về chỉ là những người không rỗng:

nonemptyLists :: [[a]] -> [[a]] 
nonemptyLists = filter (not . null) 

Without null, đây sẽ là lúng túng hơn:

nonEmptyLists = filter ([] /=) 
+4

Tuy nhiên, 'filter ([]/=)'. – kennytm

+0

Làm thế nào có thể nghịch đảo các toán hạng và nó sẵn sàng thậm chí tự nhiên hơn: 'filter (/ = [])'. Lưu ý rằng tôi luôn thích mẫu phù hợp hơn một toán tử bình đẳng (trừ khi trong trường hợp trên sử dụng nó như một hàm) – Dario

+13

Xem câu trả lời của sdcvvc: Lý do thực sự là 'null' hoạt động với bất kỳ danh sách nào, trong khi' (== [ ]) 'chỉ hoạt động với các danh sách' Eq'. –

6

Một lợi ích khi sử dụng null là nhiều container khác (ví dụ Data.Sequence, Data.ByteString, vv) có chức năng null là tốt. Điều này giúp dễ dàng chuyển sang triển khai khác chỉ bằng cách thay đổi các câu lệnh nhập của bạn.

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