2011-06-15 80 views
5

你如何用簡單的英語定義以下類型簽名:類型簽名類型列表等

Ord a => ... 

Eq a => ... 

Num a => ... 

你能描述這些含義,讓我知道它們的區別是什麼(如何我而言會解釋給別人)?

謝謝。

回答

13

這些都是「類約束」的例子:它們約束哪些類型可以用來代替它們後面的類型變量(在這種情況下爲a),要求它屬於特定的type classOrd,EqNum是類型類的示例。

  • 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

+0

我認爲人們經常期望'(==)'是一個同餘關係而不是等價關係。當然,Haskell也不會強迫你做出來。 – augustss 2011-06-15 12:48:17