[英]How to implement custom ordering for data types in Haskell?
Let's say I have a data type that represents a deck of poker cards like so 假设我有一个数据类型,表示像这样的一副扑克牌
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)
instance Show Card where show (Card vs) = show s ++ show v 实例Show Card,其中show(Card vs)= show s ++ show v
Haskell helps me already a lot by allow me to derive Eq
and Ord
without explicitly specifying those relations. Haskell通过允许我导出
Eq
和Ord
而无需明确指定这些关系,已经对我有很大帮助。 This is especially useful, because I want to use Ord
to ultimately compare the value of two hands according to Poker rules. 这特别有用,因为我想使用
Ord
根据扑克规则最终比较两只手的价值。
Now in Poker, the suits do not really matter in terms of ordering. 现在在扑克中,西装的顺序实际上并不重要。 Therefore I tried
因此我尝试了
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
This is already a bit verbose ... and it does not even work: 这已经有点冗长了……甚至不起作用:
*P054> a
♠A
*P054> b
♣A
*P054> a < b
*** Exception: P054.hs:(12,9)-(17,36): Non-exhaustive patterns in function compare
So how can I properly define an ordering on Suit
that expresses the fact that all suits are equal? 那么,如何在
Suit
上正确定义一个顺序,以表达所有西服都相等的事实呢?
You are missing several combinations, eg all with Clubs
on the right hand side. 你缺少几个组合,比如所有
Clubs
在右手边。 If all are equal, what are the possible results of compare
, regardless of the input? 如果所有条件相等,那么不管输入什么,
compare
的可能结果是什么? There is only one: EQ
. 只有一个:
EQ
。 Therefore we don't even need to look at a
or b
: 因此,我们甚至不需要查看
a
或b
:
instance Ord Suit where
compare _ _ = EQ
However, that Ord
instance is rather useless. 但是,该
Ord
实例却毫无用处。 Alternatively you can create a custom instance for Card
, 或者,您可以为
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.