次のようなポーカー カードのデッキを表すデータ型があるとします。
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
Haskell は、これらの関係を明示的に指定せずEq
に導出できるようにすることで、すでに多くのことを助けてくれます。ポーカーのルールに従って 2 つの手の値を最終的に比較する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
では、すべてのスーツが等しいという事実を表す順序付けを適切に定義するにはどうすればよいでしょうか?