想象一下,你有一个像
这样的评级Rating = OneStar | TwoStars | ThreeStars | FourStars | FiveStars
在Haskell中为这样的代数数据类型实例化/实现“Ord”的最佳方法是什么?
答案 0 :(得分:15)
最好的方法是将deriving (Eq, Ord)
添加到类型的定义中。
由于您按升序列出了构造函数,派生的Ord
实例将为您提供所需的命令。
但是,如果由于某种原因更改定义中的顺序不是一个选项,您仍然可以导出Eq,因为顺序无关紧要。给定Eq的实例,我们可以手动为Ord编写实例。定义比较最简洁的方法可能是拼出比较应返回LT的所有组合,然后简单地使用compare x y | x == y = Eq;比较_ _ = GT表示其余组合。
答案 1 :(得分:3)
如前所述,您可以派生Eq
和Ord
。或者你可以派生Enum
,然后做
instance Eq Rating where
x == y = fromEnum x == fromEnum y
或者只是拼写出来
instance Eq Rating where
OneStar == OneStar = True
TwoStar == TwoStar = True
...
_ == _ = False
答案 2 :(得分:0)
对于任何想知道的人,这是完整的,明确的样板实现:
使用罗马数字。
使用case
易于阅读。
data RN = I | II | III | IV | V
instance Eq RN where
I == I = True
I == _ = False
II == II = True
II == _ = False
III == III = True
III == _ = False
IV == IV = True
IV == _ = False
V == V = True
V == _ = False
instance Ord RN where
compare I x = case x of
I -> EQ
_ -> LT
compare II x = case x of
I -> GT
II -> EQ
_ -> LT
compare III x = case x of
I -> GT
II -> GT
III -> EQ
_ -> LT
compare IV x = case x of
V -> LT
IV -> EQ
_ -> GT
compare V x = case x of
V -> EQ
_ -> GT
答案 3 :(得分:0)
另一种实现 compare
的方法是使用已经是 Ord
实例的类型。
data Rating = OneStar | TwoStars | ThreeStars | FourStars | FiveStars
deriving (Show, Eq)
instance Ord Rating where
compare x y = compare (r2n x) (r2n y)
where
r2n OneStar = 1
r2n TwoStars = 2
r2n ThreeStars = 3
r2n FourStars = 4
r2n FiveStars = 5
我认为这个解决方案的扩展性很好。