12

有人可以向我解释如何使自定义数据类型可排序吗?

** 我不允许对 Suit 本身进行修改,例如。推导 (Eq, Ord)

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

我的尝试:

instance Ord Suit where
    compare suit1 suit2 = compare suit1 suit2

但这似乎是一个连续的循环并且不会停止。

4

3 回答 3

12

Ord 的定义看起来像(但不完全是)

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

Ordering具有三个可能的值:LT, EQ, GT.

因此,您需要定义每次比较的结果应该是什么。就像是:

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

您的实际订购可能会有所不同,但这应该会给您基本的想法。

于 2013-03-21T04:39:52.403 回答
6

编写自定义Ord实例的一种方法,您不必拼出每次比较的结果:

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

在这里,您只需要提及每个构造函数一次,您就可以轻松地决定不同的顺序。

您也可以使用compare Data.Function.on relativeRank,但这可能更容易理解。

于 2013-03-21T17:34:22.957 回答
4

您可以使用具有相同效果的独立派生。

deriving instance Enum Suit
deriving instance Ord Suit
于 2013-03-21T19:04:08.607 回答