chỉnh sửa: cung cấp một câu trả lời thực sự cho câu hỏi ...
tôi thấy cách dễ nhất để xem những gì các mẫu được phù hợp là thêm trace
báo cáo, như vậy:
import Debug.Trace
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = trace "Expr Eq pat 1" $ a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = trace "Expr Eq pat 2" $ a1+a2 == b1 + b2
-- catch any unmatched patterns
l == r = error $ "Expr Eq failed pattern match. \n l: " ++ show l ++ "\n r: " ++ show r
Nếu bạn don không bao gồm một tuyên bố cuối cùng để nắm bắt bất kỳ mẫu nào khác chưa từng có, bạn sẽ nhận được một ngoại lệ thời gian chạy, nhưng tôi thấy nó hữu ích hơn để xem dữ liệu bạn đang nhận được. Sau đó, nó thường đơn giản để xem lý do tại sao nó không phù hợp với các mẫu trước đó.
Tất nhiên bạn không muốn để điều này trong mã sản xuất. Tôi chỉ chèn dấu vết khi cần thiết rồi xóa chúng khi tôi đã hoàn thành. Bạn cũng có thể sử dụng CPP để loại bỏ chúng khỏi các bản dựng sản phẩm.
Tôi cũng muốn nói rằng tôi nghĩ rằng kết hợp mẫu là cách sai để thực hiện việc này. Bạn sẽ kết thúc với một vụ nổ tổ hợp trong số lượng các mẫu, mà nhanh chóng phát triển không thể quản lý. Nếu bạn muốn tạo ví dụ Float
cho ví dụ Expr
, bạn sẽ cần một số hàm tạo nguyên thủy hơn.
Thay vào đó, bạn có lẽ có chức năng thông dịch viên interpret :: Expr -> Double
hoặc ít nhất có thể viết một.Sau đó, bạn có thể định nghĩa
instance Eq Expr where
l == r = interpret l == interpret r
Bằng mô hình kết hợp, bạn đang chủ yếu lại bằng văn bản giải thích chức năng của bạn trong Eq
dụ. Nếu bạn muốn tạo một phiên bản Ord
, bạn sẽ lại viết lại hàm giải thích.
Nguồn
2012-03-31 01:18:35
GHC có thể phát hiện sự cố lúc biên dịch. Nếu bạn biên dịch với '-Wall', nó sẽ cảnh báo bạn về mẫu không hoàn chỉnh và cho bạn thấy trường hợp nào bạn đã bỏ lỡ. – hammar
Tùy chọn chính xác là '-fwarn-incomplete-patterns'. Kiểm tra http://stackoverflow.com/questions/7883023/algorithm-for-type-checking-ml-like-pattern-matching để xem cách hoạt động của nó. Bằng cách này, trong ví dụ của bạn tôi khuyên bạn nên viết 'eval :: Expr -> Double' và sau đó' x == y = eval x == eval y', nhưng nó vẫn còn không chuẩn. – sdcvvc
Tôi biết về các cảnh báo. Tôi muốn biết, ví dụ, tại sao một mô hình tôi nghĩ nên phù hợp, không. –