这是Learn You A Haskell中的一个示例,有关高阶函数的章节:
compareWithHundred :: (Num a, Ord a) => a -> Ordering
compareWithHundred x = compare 100 x
Run Code Online (Sandbox Code Playgroud)
虽然功能的想法对我来说很清楚,但我不确定为什么类型签名是(Num a,Ord a).我们只传递要与Int类型的函数进行比较的整数.什么Ord代表这里,为什么在类型签名中隐式传递参数?
lef*_*out 10
这不是签名的唯一可能签名.它恰好是最普遍的一个.compareWithHundred :: Int -> Ordering实际上是一个可能的实例-多态a参数可以用任何数量的订购类型,这也果然被包括instatiated Int,而且Integer,Rational,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
Run Code Online (Sandbox Code Playgroud)
并非所有数字类型都允许您订购 - 比较它们 - 这是不可能的经典示例是复数(具有"多个方向",您可以在其中订购它们).
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)
Run Code Online (Sandbox Code Playgroud)
因此,您需要同时要求参数是一个数字(因此存在要与之比较的值100)并且参数在Ord类中.这种组合约束被写入(Num a, Ord a).
我有一些东西需要补充,以防你无法收集左撇子的全面答案.
=>类型签名左侧的所有内容都是约束.阅读这样的类型:
compareWithHundred :: (Num a, Ord a) => a -> Ordering
^^^^^^^^^^^^^^ ^ ^^^^^^^^
constraints | |
argument type |
result type
Run Code Online (Sandbox Code Playgroud)
所以你只将一个参数传递给函数,因为类型签名中只有一个参数a. a是一个类型变量,只要该类型满足约束条件,就可以用任何类型替换.
该Num a说,无论你更换a与必须是数字(因此它可以是Int,Integer,Double,...),并Ord a说,它必须是可比的.leftroundabout的答案详细说明了为什么你需要两者,我只是想确保你知道如何阅读签名.
因此,在某种意义上说compareWithHundred "foobar",类型检查器表示该表达式的类型是完全合法的Ordering,但是当它试图检查是否存在Num String实例时它将会失败.
我希望这有帮助.