2

假设我有一个数据类型,它代表一副扑克牌,像这样

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

instance Show Suit where
    show Diamonds = "♦"
    show Hearts = "♥"
    show Spades = "♠"
    show Clubs = "♣"

data Value = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | Ace deriving (Eq, Ord)

data Card = Card {
      value :: Value
    , suit :: Suit
    } deriving (Eq, Ord)

实例 Show Card where show (Card vs) = show s ++ show v

EqHaskell 通过允许我推导而不Ord明确指定这些关系已经对我有很大帮助。这特别有用,因为我想用它Ord来根据扑克规则最终比较两只手的价值。

现在在扑克中,花色在排序方面并不重要。因此我尝试了

instance Ord Suit where
    compare Clubs Spades = EQ
    compare Clubs Hearts = EQ
    compare Clubs Diamonds = EQ
    compare Spades Hearts = EQ
    compare Spades Diamonds = EQ
    compare Hearts Diamonds = EQ

这已经有点冗长了......它甚至不起作用:

*P054> a
♠A
*P054> b
♣A
*P054> a < b
*** Exception: P054.hs:(12,9)-(17,36): Non-exhaustive patterns in function compare

那么,如何正确定义Suit表达所有花色都相同的排序?

4

1 回答 1

7

您缺少几个组合,例如,所有组合都Clubs在右侧。如果都相等,compare无论输入如何, 的可能结果是什么?只有一个:EQ。因此我们甚至不需要查看aor b

instance Ord Suit where
    compare _ _ = EQ

但是,该Ord实例相当无用。或者,您可以为Card

instance Ord Card where
    compare a b = compare (value a) (value b)
    -- compare = compare `on` value -- using `on` from Data.Function
    -- compare = comparing value    -- using `comparing` from Data.Ord
于 2014-10-16T17:53:39.207 回答