在比较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
显然不是任何类型的浮动-点数.
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
显然不是任何类型的浮动-点数.