gpt4 book ai didi

haskell - 制作 Ord 类的新类型实例

转载 作者:行者123 更新时间:2023-12-05 09:15:01 28 4
gpt4 key购买 nike

由于 Ord 是 Eq 的子类,我发现很难理解创建该类的新类型实例的样子。

我已经设法做到了:

    newtype NT1 = NT1 Integer

instance Eq NT1 where
(NT1 x) == (NT1 y) = x == y

instance Ord NT1 where
(NT1 x) `compare` (NT1 y) = x `compare` y

例如,如果我有一个变量 x = NT1 5 和变量 y = NT1 5 并键入 x == y 它将返回 True

我也设法做到了这一点:

instance Show NT1 where
show (NT1 n) = show n

x = NT1 5 显示为 5 而不是 NT1 5

在这之后我应该能够做这样的事情:

instance Ord NT1 where 
(>) (NT1 x)(NT1 y) = (NT1 x) > (NT1 y)
(<) (NT1 x)(NT1 y) = (NT1 x) < (NT1 y)
(<=) (NT1 x)(NT1 y) = (NT1 x) <= (NT1 y)
(>=) (NT1 x)(NT1 y) = (NT1 x) >= (NT1 y)

但这行不通。我如何使用 Ord 类执行此操作:

class  (Eq a) => Ord a  where
compare :: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
max, min :: a -> a -> a

?

最佳答案

following this I should be able to do something like this:

instance Ord NT1 where 
(>) (NT1 x)(NT1 y) = (NT1 x) > (NT1 y)
(<) (NT1 x)(NT1 y) = (NT1 x) < (NT1 y)
(<=) (NT1 x)(NT1 y) = (NT1 x) <= (NT1 y)
(>=) (NT1 x)(NT1 y) = (NT1 x) >= (NT1 y)

您在这里所做的基本上是定义一组函数,其中每个函数使用相同参数调用自身,因此这将陷入无限循环。

确实如此,例如你定义:

instance Ord NT1 where 
(>) (NT1 x)(NT1 y) = (NT1 x) > (NT1 y)

所以这意味着你说 NT1 x > NT1 y , 给出 NT1 x > NT1 y , 但当然这并没有真正做任何事情。

好处是你不需要定义所有这些函数:Haskell 已经在 Ord 中构建了许多其他函数。 typeclass 在其他方面,所以如果我们看一下 documentation for Ord ,我们看到:

Minimal complete definition

compare | (<=)

所以执行compare , 或 (<=)足够了。 Haskell 还可以基于该实现计算其他比较,以及 min。 , max等等。您可以实现这些,例如,如果有更有效的方法来检查 NT1 x < NT1 y比打电话 compare并检查结果是否为 LT .

您的实现方式如下:

newtype NT1 = NT1 Integer

instance Eq NT1 where
(NT1 x) == (NT1 y) = x == y

instance Ord NT1 where
(NT1 x) `compare` (NT1 y) = x `compare` y

因此就足够了,例如:

Prelude> NT1 14 < NT1 25
True

从而正确地比较了两个对象。

这也是一个简单的实现,事实上两个 NT1如果构造函数相同(这里只有 一个 构造函数),则对象相等,并且参数是一个简单的实现。

Ord还有一个“流行”的实现:一个对象被认为比另一个对象小,因为第一个对象的构造函数在第二个对象的构造函数之前定义,或者如果构造函数相同,则通过比较它们的参数较小“按字典顺序”。

Haskell 支持这些类型的实现,您可以使用 deriving类型定义中的子句:

newtype NT1 = NT1 Integer <b>deriving (Show, Eq, Ord)</b>

因此我们在这里“自动”实现了 Eq , OrdShow类型类。对于 Show它是通过首先显示构造函数的名称后跟 show 来实现的的论据。它还在某些不明确的情况下添加括号(尽管规则有点复杂)。

我们也可以,喜欢@DanielWagner says我们自己实现这些功能,包括:

instance Ord NT1 where 
compare (NT1 x) (NT1 y) = compare x y
(>) (NT1 x)(NT1 y) = <b>x > y</b>

因此我们在这里NT1来调用它右侧的数据构造函数,否则我们只需使用相同的参数再次调用此函数。通过上述实现,我们调用 x > y , 所以 (>)但是在构造函数中包含的参数

关于haskell - 制作 Ord 类的新类型实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53270609/

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