Haskell,一个参数的多个类型类

标签 haskell types

这是《Learn You A Haskell》中有关高阶函数的章节中的一个示例:

compareWithHundred :: (Num a, Ord a) => a -> Ordering  
compareWithHundred x = compare 100 x  

虽然该函数的想法对我来说很清楚,但我不确定为什么类型签名是 (Num a, Ord a)。我们只传递要与 Int 类型的函数进行比较的整数。 Ord 在这里代表什么,为什么在类型签名中隐式传递参数?

最佳答案

这不是此签名的唯一可能签名。它恰好是最通用的一个。 compareWithHundred::Int -> Ordering 实际上是一个可能的实例化 - 多态 a 参数可以用任何可排序的数字类型来实例化,这确实包括 Int,还有整数有理数 double ...

Prelude> let compareWithHundred :: (Num a, Ord a) => a -> Ordering; compareWithHundred x = compare 100 x
Prelude> compareWithHundred (99 :: Int)
GT
Prelude> compareWithHundred (100.3 :: Double)
LT

并非所有数字类型都允许您对它们进行排序比较 - 无法进行排序比较的经典示例是复数(它们具有“多个方向”,您可以对它们进行排序) .

Prelude Data.Complex> compareWithHundred (100 :+ 30 :: Complex Double)

<interactive>:10:1:
    No instance for (Ord (Complex Double))
      arising from a use of ‘compareWithHundred’
    In the expression: compareWithHundred (100 :+ 30 :: Complex Double)
    In an equation for ‘it’:
        it = compareWithHundred (100 :+ 30 :: Complex Double)

因此,您需要要求参数是数字(因此存在要比较的值 100),并且参数位于 Ord 类中。该组合约束写作(Num a, Ord a)

关于Haskell,一个参数的多个类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40813463/

相关文章:

Haskell 计算器 - 运算顺序

c# - 如何 "store"类型(不是 `Type` 对象)以供将来使用?

java - 将 char[] 转换为 byte[] 不丢失 'bits'

typescript - 映射具有未知深度的通用 TypeScript 接口(interface)

haskell - 第一位的索引

haskell - 将 Data.RVar.RVar [Char] 转换为 [Char]

haskell - tf-random不会安装在Docker容器中

haskell - 我应该在哪里以及为什么要使用额外的空模式?

mysql - 更改数据库中列的数据类型

typescript - 如何理解类型 any、unknown、{} 之间以及它们与其他类型之间的关系?