gpt4 book ai didi

haskell - 为什么 enum 类型类不是 ord 类型类的子类?

转载 作者:行者123 更新时间:2023-12-02 16:12:07 24 4
gpt4 key购买 nike

我想知道enum类型类不继承ord类型类的原因。枚举中的 succ 函数本质上对值强加了一个顺序,但 ord 不是必需的约束。

编辑:此外,对于类型类中的其他函数,似乎有一个关于为它们定义 ord 运算符的隐含假设。如图所示https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#v:enumFromTo

a possible implementation being enumFromTo n m | n <= m = n : enumFromTo (succ n) m | otherwise = []

最佳答案

Ord类型类旨在表示订单,其中需要传递性:if a < bb < c ,然后a < c .

父类(super class)对于类实例的定义是必需的。

Enum ,尽管它可能对其元素强加一个顺序(尽管不一定是全序),但不使用要求全序。

举个例子,考虑每个人最喜欢的决策算法:

data RPS = Rock | Paper | Scissors deriving (Eq, Ord)

instance Enum RPS where
succ Rock = Paper
succ Paper = Scissors
succ Scissors = Rock

Ord从定义派生的实例是完整的、简单的:Rock是最小的元素,Scissors最大的,和Paper介于两者之间。

此枚举所隐含的顺序并不完整。鉴于succ ,您可能会假设 Rock < PaperPaper < Scissors ,但随后 Rock < Scissors应该是 true,但 succ Scissors = Rock 并未暗示这一点。 .

Ord实例对于定义 Enum 没有用处如上所示。

<小时/>

不幸的是,正确的实例声明应该使用 toEnumfromEnum ,可以从中导出所有其他方法(包括 succ )。这使得定义更加冗长。遵循 DaysOfWeek 的型号

instance Enum RPS where
-- *We* know that n `mod` 3 has 3 possible results, but
-- the exhaustivity checker does not, so use _ in place of 2
toEnum n = case n `mod` 3 of
0 -> Rock
1 -> Paper
_ -> Scissors

fromEnum Rock = 0
fromEnum Paper = 1
fromEnum Scissors = 2

-- The generated definitions don't handle wrapping. Without these,
-- [Paper..Rock] would produce [], not [Paper, Scissors, Rock].
enumFromTo wd1 wd2
| wd1 == wd2 = [wd1]
enumFromTo wd1 wd2 = wd1 : enumFromTo (succ wd1) wd2
enumFromThenTo wd1 wd2 wd3
| wd2 == wd3 = [wd1, wd2]
enumFromThenTo wd1 wd2 wd3 = wd1 : enumFromThenTo wd2 (toEnum $ (2 * fromEnum wd2) - (fromEnum wd1)) wd3

关于haskell - 为什么 enum 类型类不是 ord 类型类的子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58761160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com