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!我对你的问题有点困惑——你是在问为什么类型类 OrdNum 首先存在?或者您是在问为什么 LearnYouAHaskell 教的是第一个而不是第二个? 你说得对——Integral 会更好。 replicate' 3.3 5 不应该这样做。 Integral 暗示 NumOrd @FrankSchmitt 我试图了解其中的区别。 【参考方案1】:

Haskell 始终致力于构建最通用的类​​型签名。如果我们看一下实现:

replicate' :: (Num i, Ord i) => i -> a -> [a]  
replicate' n x  
    | n <= 0    = []  
    | otherwise = x:replicate' (n-1) x

我们看到(&lt;=) :: Ord a =&gt; a -&gt; a -&gt; Bool 函数应用于n,我们在递归中计算n-1(使用(-) :: Num a =&gt; a -&gt; a -&gt; a)。因此,最通用的类​​型签名将在该数字上添加 NumOrd 类型约束。

因此我们可以调用replicate' 3.1415 1,它会返回前四个项目。但这样做可能是荒谬的。

Integral 类型类是整数类型类。它支持整数除法。任何Integral 类型都必须是RealEnum 类型类的成员。

作为Real 类型类成员的类型,应该支持函数toRational :: Real a =&gt; a -&gt; Rational 将该数字转换为Rational,此外还应该是NumOrd 类型类的成员。

因此,这意味着如果一个类型是 Integral 类型类的成员,那么它也是 NumEnumOrdReal 的成员。因此,您使类型更具限制性。但我认为在replicate' 的背景下,这样做非常有意义。

请注意,它可能不适合写:

replicate' :: (Num a, Ord a) => a -> b -> [b]
replicate' 0 x = []
replicate' n x = x:replicate' (n-1) x

如果我们在这里调用replicate (-3) 1replicate 3.14 1(如@leftroundabout pointed out),我们将获得1s的无限列表。

【讨论】:

注:在replicate' 0 x = [] 实现的情况下,replicate' 3.14生成一个无限列表!

以上是关于Haskell:(Num a,Ord a)和(Integral a)之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

python数据结构

如何使用“ord”函数在 Haskell 中将 Char 转换为 Int?

Haskell:使用 List Monad 计算周期

使用 ord 搜索字符串比使用 'in' 方法慢

运行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