这是《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/