[英]How to implement custom ordering for data types in Haskell?
假设我有一个数据类型,表示像这样的一副扑克牌
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,其中show(Card vs)= show s ++ show v
Haskell通过允许我导出Eq
和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
上正确定义一个顺序,以表达所有西服都相等的事实呢?
你缺少几个组合,比如所有Clubs
在右手边。 如果所有条件相等,那么不管输入什么, compare
的可能结果是什么? 只有一个: EQ
。 因此,我们甚至不需要查看a
或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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.