如何在Haskell中实现数据类型的自定义排序?

时间:2014-10-16 17:50:23

标签: haskell algebraic-data-types ord

假设我有一个代表一副扑克牌的数据类型

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 v s)= show s ++ show v

Haskell通过允许我在没有明确指定这些关系的情况下派生EqOrd来帮助我。 这特别有用,因为我想根据扑克规则使用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上正确定义表达所有诉讼相等的事实的排序?

1 个答案:

答案 0 :(得分:7)

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

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