你如何用簡單的英語定義以下類型簽名:類型簽名類型列表等
Ord a => ...
Eq a => ...
Num a => ...
你能描述這些含義,讓我知道它們的區別是什麼(如何我而言會解釋給別人)?
謝謝。
你如何用簡單的英語定義以下類型簽名:類型簽名類型列表等
Ord a => ...
Eq a => ...
Num a => ...
你能描述這些含義,讓我知道它們的區別是什麼(如何我而言會解釋給別人)?
謝謝。
這些都是「類約束」的例子:它們約束哪些類型可以用來代替它們後面的類型變量(在這種情況下爲a
),要求它屬於特定的type class。 Ord
,Eq
和Num
是類型類的示例。
Ord a => ...
意味着a
是具有與其相關聯的順序自然概念類型。例如,整數可以自然地從小到大排列。用數學術語,a
上存在total order。一個需要這個約束的函數的一個明顯的例子是sort :: Ord a => [a] -> [a]
;讀這個簽名,說sort
只適用於可以彼此相關的東西列表。
Eq a => ...
意味着a
是一種類型,其成員之間可以相互比較一些概念的平等。用數學術語,a
上存在equivalence relation。請注意,這是Ord
的超類,這意味着任何具有排序概念的東西都必須具有等價的概念。一個需要這個約束的函數的例子是elem :: Eq a => a -> [a] -> Bool
(它確定一個列表是否包含給定的元素);閱讀這個簽名,說elem
只適用於可以相互比較的事物列表的平等。如果你考慮如何自己寫elem
,那應該是有道理的。
Num a => ...
意味着a
是數字類型,這意味着它支持一些基本算術運算:+
,*
,-
,abs
。我相信這與ring的數學概念大致相似。基本上所有你認爲是「數字類型」的類型都屬於這個類別:Int
,Double
等等。如果函數被寫入通常用於任何類型的數字,你會在簽名前面看到Num a =>
約束。例如,sum :: Num a => [a] -> a
,其中包括數字列表中的所有元素,可以在[Int]
,[Double]
,[Rational]
等等上同樣有效地工作......所有它要做的就是將其內容加起來,不管它們是什麼樣的數字。但他們必須是數字!
基本上,這些類型的類/約束是一種方法來「功能有效的重載」。我們可以使用各種類型的(==) :: Eq a => a -> a -> Bool
,但不只是任何類型。有些東西,比如函數,沒有意義去比較它們之間的平等(也許是因爲這種類型的平等不可判定),而它從來沒有有意義地比較不同的兩種東西是否相等使用Java,您可以在其中比較可能不同類型的任何兩個對象是否相等)。
爲了進一步(非常方便)讀取類型類別和約束,我強烈建議Learn You a Haskell。
我認爲人們經常期望'(==)'是一個同餘關係而不是等價關係。當然,Haskell也不會強迫你做出來。 – augustss 2011-06-15 12:48:17