Kiểu đầu tiên được coi là kiểu tốt hơn, vì 2 lý do.
Trước hết: Nhiều người sẽ nói rằng có vẻ tốt hơn, vì bạn không phải nhập tất cả các số ==
. Đây là một lý do rất chủ quan, tất nhiên. Ngoài ra, bạn sẽ thường thậm chí không đưa ra một tuyên bố trường hợp mới, nhưng chỉ phù hợp với các đối số trong danh sách đối số chức năng như vậy:
foo 1 b c = ... -- etc
...
foo _ b c = ... -- for the "otherwise" part
Điều này làm cho mã thậm chí nhỏ gọn hơn và dễ đọc, mà nhiều người thích.
Thứ hai, thực sự có sự khác biệt ngữ nghĩa. Hãy tưởng tượng rằng bạn có một kiểu dữ liệu như thế này:
data Cake = Apple | Cheese | Cream
Nếu bạn sử dụng phương pháp đầu tiên, bạn kết hợp với các nhà thầu trong biểu thức case..of
:
case a of
Apple -> "fruit"
_ -> "not fruit"
Tuy nhiên, nếu bạn cố gắng làm một bảo vệ biểu hiện của một số loại, như thế này:
| a == Apple = "fruit"
| otherwise = "not fruit"
... nó sẽ không thực sự làm việc, bởi vì loại Cake
không có một thể hiện Eq
, do đó bạn không thể sử dụng ==
để so sánh hai giá trị. Giới thiệu một cá thể Eq
(với deriving (Eq)
sau khi định nghĩa dữ liệu) không phải lúc nào cũng muốn, do đó không phải thực hiện trong trường hợp này có thể là đáng kể.
Trong ví dụ đầu tiên của bạn, bạn không nên sử dụng 'nếu không' như thế. Những gì nó làm là nó sẽ giới thiệu một biến mới gọi là 'else = a', có thể dẫn đến lỗi tinh tế. Bạn nên làm '_ -> lỗi" ... "' thay thế. – dflemstr
@dflemstr cảm ơn thông tin và giải thích. – Nomics
Là mẹo chung về ngôn ngữ chung, tôi thích viết các mã con trên mã tiếp theo và luôn có cùng mức thụt đầu dòng. Điều này bảo vệ bạn khỏi phải liên kết lại các dòng còn lại nếu đầu tiên thay đổi chiều dài (có lẽ do foo đang được đổi tên hoặc dòng nào đó) – hugomg