Haskell:(Num a,Ord a)和(Integral a)之间的区别
Posted
技术标签:
【中文标题】Haskell:(Num a,Ord a)和(Integral a)之间的区别【英文标题】:Haskell: Difference between (Num a, Ord a) & (Integral a) 【发布时间】:2019-09-26 05:47:19 【问题描述】:以下两个声明都适用于replicate' 3 5
。我无法理解为什么你需要 Num 和 Ord 而 Integral 会这样做。第二个是我想出的,第一个在这里 - http://learnyouahaskell.com/recursion。
仅使用 Integral 我会失去什么?
1
replicate' :: (Num a, Ord a) => a -> b -> [b]
replicate' 0 x = []
replicate' n x = x:replicate' (n-1) x
2
replicate' :: (Integral a) => a -> b -> [b]
replicate' 0 x = []
replicate' n x = x:replicate' (n-1) x
注意:在下面威廉的回答之后,我需要在这里给出一些澄清(他在没有这个澄清的情况下理解了这个问题)。 http://learnyouahaskell.com/recursion中的代码是
replicate' :: (Num i, Ord i) => i -> a -> [a]
replicate' n x
| n <= 0 = []
| otherwise = x:replicate' (n-1) x
不是我在 1 中提到的。Willem 的回复解释了所有三个 sn-ps。
另外,Haskell type definition, => etc 也有相关问题
【问题讨论】:
欢迎来到 SO!我对你的问题有点困惑——你是在问为什么类型类Ord
和 Num
首先存在?或者您是在问为什么 LearnYouAHaskell 教的是第一个而不是第二个?
你说得对——Integral
会更好。 replicate' 3.3 5
不应该这样做。
Integral
暗示 Num
和 Ord
。
@FrankSchmitt 我试图了解其中的区别。
【参考方案1】:
Haskell 始终致力于构建最通用的类型签名。如果我们看一下实现:
replicate' :: (Num i, Ord i) => i -> a -> [a]
replicate' n x
| n <= 0 = []
| otherwise = x:replicate' (n-1) x
我们看到(<=) :: Ord a => a -> a -> Bool
函数应用于n
,我们在递归中计算n-1
(使用(-) :: Num a => a -> a -> a
)。因此,最通用的类型签名将在该数字上添加 Num
和 Ord
类型约束。
因此我们可以调用replicate' 3.1415 1
,它会返回前四个项目。但这样做可能是荒谬的。
Integral
类型类是整数类型类。它支持整数除法。任何Integral
类型都必须是Real
和Enum
类型类的成员。
作为Real
类型类成员的类型,应该支持函数toRational :: Real a => a -> Rational
将该数字转换为Rational
,此外还应该是Num
和Ord
类型类的成员。
因此,这意味着如果一个类型是 Integral
类型类的成员,那么它也是 Num
、Enum
、Ord
和 Real
的成员。因此,您使类型更具限制性。但我认为在replicate'
的背景下,这样做非常有意义。
请注意,它可能不适合写:
replicate' :: (Num a, Ord a) => a -> b -> [b]
replicate' 0 x = []
replicate' n x = x:replicate' (n-1) x
如果我们在这里调用replicate (-3) 1
或replicate 3.14 1
(如@leftroundabout pointed out),我们将获得1
s的无限列表。
【讨论】:
注:在replicate' 0 x = []
实现的情况下,replicate' 3.14
将也生成一个无限列表!以上是关于Haskell:(Num a,Ord a)和(Integral a)之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
如何使用“ord”函数在 Haskell 中将 Char 转换为 Int?
运行python代码报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 91: ord
Python error: ascii’/'utf-8′ codec can’t decode byte 0xb8 in position 50: ord