2013-03-21 18 views
7

Ai đó có thể giải thích cho tôi làm cách nào để tạo một kiểu dữ liệu tùy chỉnh có thể thực hiện được không?Làm cho một kiểu dữ liệu tùy chỉnh có thể là

** Tôi không được phép sửa đổi bản thân Suit, ví dụ: phát sinh (Eq, Ord)

data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq) 

Nỗ lực của tôi:

instance Ord Suit where 
    compare suit1 suit2 = compare suit1 suit2 

nhưng điều đó dường như đi vào một vòng lặp liên tục và không ngừng.

+0

Bạn cần phải chỉ rõ cách so sánh nó. Tôi không biết cách nào phổ biến để quyết định liệu Hearts có lớn hơn Câu lạc bộ hay không. Sau đó, bạn có thể sử dụng đối sánh mẫu. – jozefg

+0

Tôi thực sự không cần chúng theo bất kỳ thứ tự cụ thể nào, tôi chỉ cần chúng được sắp xếp cạnh nhau. – rlhh

+0

Xin lỗi? Vì vậy, về cơ bản bạn có thể chỉ cần chọn một số thứ tự tùy ý? – jozefg

Trả lời

8

Định nghĩa of Ord trông giống như sau (nhưng không hoàn toàn)

class Ord a where 
    compare :: a -> a -> Ordering 

Ordering có ba giá trị có thể: LT, EQ, GT.

Vì vậy, bạn cần xác định kết quả của từng so sánh. Một cái gì đó như:

instance Ord Suit where 
    compare Clubs Diamonds = LT 
    compare Diamonds Clubs = GT 
    compare Diamonds Diamonds = EQ 
    compare Diamonds _  = LT -- Diamonds are lower than everything besides Clubs and Diamonds 

Đặt hàng thực tế của bạn có thể khác, nhưng điều đó sẽ cung cấp cho bạn ý tưởng cơ bản.

+0

Có cách nào để tôi có thể sử dụng thứ tự chuỗi mặc định để đạt được điều gì đó tương tự không? (Xem xét tôi đang làm nhiều hơn một nhóm hơn phân loại) – rlhh

+0

Có thể xác định nó như là một thể hiện của chương trình và sau đó chỉ cần làm 'so sánh = trên so sánh show' – jozefg

+0

@jozefg Nó đã được tuyên bố là một thể hiện của Hiển thị, nhưng làm thế nào tôi thực sự đúng mã trong Haskell? Ví dụ: 'show Clubs =" C "' – rlhh

3

Một cách để viết một ví dụ tùy chỉnh Ord nơi bạn không cần phải giải thích rõ ràng là kết quả của từng so sánh là:

instance Ord Suit where 
    compare a b = compare (relativeRank a) (relativeRank b) where 
     relativeRank Diamonds = 1 
     relativeRank Clubs = 2 
     relativeRank Hearts = 3 
     relativeRank Spades = 4 

Ở đây, bạn chỉ cần đề cập đến từng nhà xây dựng một lần, và bạn có thể dễ dàng quyết định một thứ tự khác.

Bạn cũng có thể sử dụng compare Data.Function.on relativeRank, nhưng điều này có thể dễ hiểu hơn.

4

Bạn có thể sử dụng standalone deriving có cùng tác dụng.

deriving instance Enum Suit 
deriving instance Ord Suit 
Các vấn đề liên quan