2013-04-28 14 views
4

我見過很多「真多形性」的部分定義,例如herehere,但我無法找到兩個具體示例差別的明顯例子。「真多態性」的例子? (最好使用Haskell)

我明白,重載+運算符是某種形式的多態性,它在Haskell和C++中的實現方式不同。有人能夠準確地顯示兩種語言的例子有什麼不同嗎?

+0

維基百科文章中沒有提到「真正的多態性」。 – delnan 2013-04-28 17:02:02

+0

@delnan你說得對,我很抱歉。我使用那篇文章來幫助我理解一般多態性的不同類型 – CodyBugstein 2013-04-28 20:13:14

回答

6

您正在尋找的術語是「參數多態性」,它與「ad-hoc多態性」不同。

參數多態性的一個例子是在類型簽名Nothing

Nothing :: Maybe a 

在類型可以是任何類型的可設想的a,由於Nothing棲息在所有Maybe秒。我們說a是參數多態,因爲它可以是任何類型。

現在考慮此類型:

Just 1 :: (Num b) => Maybe b 

此番b不能是任何類型的:它只能是一種類型,是Num一個實例。我們說b是ad-hoc多態的,因爲它可以是由類Num的實例給出的一組類型中的任何成員。

因此,回顧一下:

  • 參數多態:可以是任何類型

  • 特設多態:由一種類約束

3

有三種類型你將經常遇到的多態性(使用C++和Haskell示例)。

函數式語言中的參數多態性是類型系統的一個特性,其中函數的類型是一個通過類型變量量化的表達式。輸入類型限制了簽名中的自由參數,這決定了輸出類型。例如,map函數接受一個函數作爲它的第一個參數,它決定了輸入列表和輸出列表的類型。

map :: (a -> b) -> [a] -> [b] 

在類型理論的說法簽名通常寫作:

∀ a. ∀ b. (a -> b) -> [a] -> [b] 

C++可以實現通過模板參數多態性的影響,但在我看來很脆(即導致模糊的編譯錯誤)而缺乏發現功能語言中的形式主義:

template <class T> 
T add(T a, T b) { 
    return a+b; 
} 

特設多態是當functi當用不同的類型簽名「查看」時,具有相同名稱的ons的行爲會有所不同。在Haskell中,這是用類型類表示的。(+)簽名中的a類型與實現Num類型類的類型是有界的。

(+) :: Num a => a -> a -> a 

class Num a where 
    (+) :: a -> a -> a 

instance Num Int where 
    (+) = plusInt 

亞型多態性。在Haskell中不存在,但其他語言(Scala,ML)具有亞型多態性。在面向對象的語言中,這通常是一種語言功能,其中不同的對象實例實現具有相同名稱的方法或屬性調用,並根據對象模型的語義進行調度。以C++爲例:

class Animal { 
public: 
virtual void speak() = 0; 
}; 

class Cat : public Animal { 
public: 
void speak() { 
    printf("Meow"); 
} 
}; 

class Dog : public Animal { 
public: 
void speak() { 
    printf("Woof"); 
} 
}; 

要記住關於多態性的事情是將核心思想與實現分開。例如,ad-hoc多態與type-classes不同,它只是它的一個表達式。

+0

當你說ML有亞型多態性時,你指的是OCaml嗎? – sepp2k 2013-04-28 20:17:48

+0

如果你看看我提供的鏈接(http://www.haskell.org/haskellwiki/Haskell_Tutorial_for_C_Programmers),它似乎認爲'+'運算符是Haskell中「真多態性」的一個例子,其中在你的答案中,你用它來演示Ad-hoc多態性。我很困惑 – CodyBugstein 2013-04-28 20:32:10

+1

在這篇文章的情況下,它是說C不支持任何類型的多態。如果你將「真正的多態性」理解爲「任何類型的多態性」,它會更有意義。 – 2013-04-28 22:10:47