在比较Haskell中的数字时,数据ord可以只用RealFloat代替吗?

Can data ord be replaced with only RealFloat in comparing numbers in Haskell?

maxs :: (RealFloat a) => a -> a -> a
maxs a b
    | a>b = a
    | otherwise = b


maxs :: (Ord a) => a -> a -> a
maxs a b
    | a>b = a
    | otherwise = b

我正在尝试使用 Haskell 编写 max 函数。这两个似乎都有效。我写了第一个,后一个来自这本书。我的问题是,它们之间有什么区别?它们可以相互替代吗?

ord class 用于完全有序的数据类型。但在这种情况下,顺序似乎并不重要。

假设我写了两个函数:

f :: (a, b) -> a
f (x, y) = x

g :: (Int, Bool) -> Int
g (x, y) = x

有什么区别?函数 g 不太通用,因为它的类型比 f 的类型更精确。从某种意义上说,g 是 "artificially restricted" 仅适用于 (Int, Bool),而它可以适用于任何产品类型。

你对$\max$的两个定义情况类似。一个比另一个更通用,但不是因为它做得更聪明,而是因为你声明其中一个可以在任何 Ord 个实例上工作,而另一个只在 RealFloat 个实例上工作。

顺便说一句,Ord在这里或多或少是不可避免的,因为如果你有max,你可以定义$\leq$ $$x \leq y \iff \max(x,y) = y.$$

RealFloat 意味着 RealFrac 意味着 Real 又意味着 Ord.

换句话说,作为 RealFloat 实例的每个类型都必须 也是 Ord 的实例。因此,both 这些函数都需要 Ord(这就是定义您尝试使用的“<”运算符的原因)。但是第一个毫无意义 需要一堆与浮点数有关的东西(例如 cos 函数)。

顺序肯定确实重要;这就是 max 函数的全部要点。就是求最大值。没有排序,没有最大值!

另一方面,通过使用 RealFrac,您无法(例如)找到最大值 String,因为 String 显然不是任何类型的浮动-点数.