Các lỗi ngay lập tức ở đây là Animal
được xác định hai cấu trúc dữ liệu, mà không có gì để làm với Cat
: Khái niệm Cat
là loại Animal
, trong khi các biểu hiện BigCat
là loại Cat
.
Để tạo kiểu dữ liệu lồng nhau trong thời trang đơn giản, bạn sẽ cần phải thực hiện các loại Cat
một cuộc tranh cãi với các nhà xây dựng có liên quan:
data Cat = BigCat | SmallCat
data Animal = Cat Cat | Dog
Sau đó bạn có thể làm một cái gì đó như thế này:
bigger (Cat SmallCat) (Cat BigCat) = False
bigger (Cat BigCat) (Cat SmallCat) = True
bigger Dog (Cat _) = True
bigger (Cat _) Dog = False
Điều này trở nên quá vụng về nếu mở rộng vượt ra ngoài một ví dụ tầm thường, tuy nhiên, sự dư thừa trong loại Cat
là đau đớn, và hai cách sử dụng khác nhau của mã định danh Cat
là không cần thiết gây nhầm lẫn. Một cải tiến nhẹ là để tránh conflating kích thước với loài, và thay vào đó làm một cái gì đó như thế này:
data Size = Big | Small
data Species = Cat | Dog
data Animal = Animal Species Size
Một lợi thế ở đây là bạn có thể dễ dàng mở rộng hoặc loại mà không cần phải thêm càng nhiều vô nghĩa soạn sẵn như nếu không sẽ được yêu cầu . Tuy nhiên, cả hai đều rất ngớ ngẩn như bất cứ điều gì khác hơn là ví dụ đồ chơi và trong thực tế sử dụng có rất nhiều khả năng là một cách tiếp cận tốt hơn nhiều mà sẽ là thích hợp hơn. Nếu các loại thực sự là số đếm đơn giản có ý nghĩa hơn mèo và chó, thì deriving
Ord
, Enum
, & c. thích hợp hơn với các mục đích đặc biệt. Nếu mục đích là một cách thức kết thúc mở rộng hơn của việc mô hình hóa các thực thể với các thuộc tính khác nhau, thì đáng để suy nghĩ về các thiết kế khác phù hợp hơn với vấn đề thực tế.
Nguồn
2011-12-02 17:24:50
"Tại sao sẽ không thừa nhận rằng một con mèo lớn hay con mèo nhỏ là một con vật?" - Bởi vì nó không phải. 'BigCat :: Cat' và' SmallCat :: Cat', nhưng 'Cat :: Animal'. * Constructor * 'Cat' không liên quan đến * type *' Cat'. – delnan