這是一個學習的榜樣你一個Haskell,對高階函數一章:哈斯克爾,多類型的類一個參數
compareWithHundred :: (Num a, Ord a) => a -> Ordering
compareWithHundred x = compare 100 x
雖然功能的思路是清晰的對我來說,我不知道爲什麼類型簽名是(Num a,Ord a)。我們只傳遞要與Int類型的函數進行比較的整數。 Ord
在這裏代表什麼,爲什麼在類型簽名中隱式傳遞參數?
這是一個學習的榜樣你一個Haskell,對高階函數一章:哈斯克爾,多類型的類一個參數
compareWithHundred :: (Num a, Ord a) => a -> Ordering
compareWithHundred x = compare 100 x
雖然功能的思路是清晰的對我來說,我不知道爲什麼類型簽名是(Num a,Ord a)。我們只傳遞要與Int類型的函數進行比較的整數。 Ord
在這裏代表什麼,爲什麼在類型簽名中隱式傳遞參數?
這不是簽名的唯一可能的簽名。它恰好是一個最通用的之一。 compareWithHundred :: Int -> Ordering
實際上是一個可能的實例 - 多態a
參數可以用任何數量的訂購類型,並果然包括Int
,也Integer
,Rational
,Double
被instatiated ...
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)
。
我有些事要補充,以防你無法從leftaroundabout的完整答案中收集一些東西。
類型簽名中=>
左側的所有東西都是約束條件。閱讀類型是這樣的:
compareWithHundred :: (Num a, Ord a) => a -> Ordering
^^^^^^^^^^^^^^ ^ ^^^^^^^^
constraints | |
argument type |
result type
所以,你只能傳遞一個函數參數,因爲只有在一個類型簽名,a
說法。 a
是一個類型變量,只要該類型滿足約束條件,可以用任何類型來替換。
的Num a
說,無論你更換a
與必須是數字(所以可以Int
,Integer
,Double
,...),以及Ord a
說,它必須是可比的。 leftroundabout的答案更詳細地解釋了爲什麼你需要這兩個,我只是想確保你知道如何閱讀簽名。
因此,在某種意義上說compareWithHundred "foobar"
是完全合法的,類型檢查器說這個表達式的類型是Ordering
,但是當它試圖檢查是否存在Num String
實例時會失敗。
我希望這會有所幫助。