nó là gì mà hạn chế, do đó bạn không thể mô hình phù hợp về nhà xây dựng với một tham số hạn chế kiểu lớp?
Khi bạn khớp mẫu trên một hàm tạo rõ ràng, bạn cam kết một đại diện kiểu dữ liệu cụ thể. Kiểu dữ liệu này không được chia sẻ giữa tất cả các cá thể của lớp và do đó không thể viết một hàm hoạt động cho tất cả các cá thể theo cách này.
Thay vào đó, bạn cần phải kết hợp các hành vi khác nhau muốn của bạn với mỗi trường hợp, như vậy:
class C a where
toString :: a -> String
draw :: a -> String
instance C MyType1 where
toString v = "MyType1"
draw (MyObj11 x) = "11"
draw (MyObj12 x y) = "12"
instance C MyType2 where
toString v = "MyType2"
draw (MyObj22 x y) = "22"
data MyType1 = MyObj11 Int | MyObj12 Int Int
data MyType2 = MyObj21 Int | MyObj22 Int Int
test :: C a => a -> String
test x = draw x
Các chi nhánh của gốc test
chức năng của bạn bây giờ được phân phối giữa các trường.
Một số thủ thuật thay thế liên quan đến việc sử dụng class-associated data types (nơi bạn chứng minh trình biên dịch là loại dữ liệu được chia sẻ giữa tất cả các trường hợp) hoặc view patterns (cho phép bạn tổng quát mẫu phù hợp).
Xem mẫu
Chúng ta có thể sử dụng xem mẫu để làm sạch các mối liên hệ giữa mô hình kết hợp và kiểu lớp trường hợp, một chút, cho phép chúng ta xấp xỉ mô hình kết hợp giữa các trường hợp bởi mô hình kết hợp trên một chia sẻ kiểu.
Đây là một ví dụ, trong đó chúng tôi viết một hàm, với hai trường hợp, cho phép chúng ta khớp mẫu với bất kỳ thứ gì trong lớp.
{-# LANGUAGE ViewPatterns #-}
class C a where
view :: a -> View
data View = One Int
| Two Int Int
data MyType1 = MyObj11 Int | MyObj12 Int Int
instance C MyType1 where
view (MyObj11 n) = One n
view (MyObj12 n m) = Two n m
data MyType2 = MyObj21 Int | MyObj22 Int Int
instance C MyType2 where
view (MyObj21 n) = One n
view (MyObj22 n m) = Two n m
test :: C a => a -> String
test (view -> One n) = "One " ++ show n
test (view -> Two n m) = "Two " ++ show n ++ show m
Lưu ý cách mà cú pháp ->
cho phép chúng tôi gọi lại cho đúng view
chức năng trong mỗi trường hợp, nhìn lên một mã hóa kiểu dữ liệu tùy chỉnh cho mỗi loại, để phù hợp với mô hình trên đó.
Thiết kế Thách thức là để tìm ra một loại quan điểm cho rằng bắt tất cả các hành vi biến thể bạn quan tâm.
Trong câu hỏi ban đầu của bạn, bạn muốn mỗi nhà xây dựng để có một hành vi khác nhau, do đó, thực sự không có lý do để sử dụng kiểu xem (gửi trực tiếp đến hành vi đó trong từng trường hợp đã hoạt động đủ tốt).
điều này có thể có ý nghĩa nếu các lớp của haskell đã bị đóng - nghĩa là bạn có thể chỉ định hành vi cho mọi triển khai. Nhưng các lớp Haskell được mở - nên 'test' làm gì nếu đưa ra một giá trị kiểu' SomeoneElsesType' khi 'instance SomeClass SomeoneElsesType trong đó toString v =" mwahahahah "'? câu trả lời dons là cách thích hợp để xử lý điều này. – rampion
Câu hỏi đó dường như rõ ràng đối với tôi: nó sẽ làm bất cứ điều gì phù hợp với mô hình cho biết nó nên.Và nếu không có mẫu phù hợp với nó, nó sẽ cung cấp cho một lỗi như giống như bất kỳ tình huống như vậy. Tôi không thấy sự khác biệt. – mentics