我見過很多「真多形性」的部分定義,例如here和here,但我無法找到兩個具體示例差別的明顯例子。「真多態性」的例子? (最好使用Haskell)
我明白,重載+
運算符是某種形式的多態性,它在Haskell和C++中的實現方式不同。有人能夠準確地顯示兩種語言的例子有什麼不同嗎?
我見過很多「真多形性」的部分定義,例如here和here,但我無法找到兩個具體示例差別的明顯例子。「真多態性」的例子? (最好使用Haskell)
我明白,重載+
運算符是某種形式的多態性,它在Haskell和C++中的實現方式不同。有人能夠準確地顯示兩種語言的例子有什麼不同嗎?
您正在尋找的術語是「參數多態性」,它與「ad-hoc多態性」不同。
參數多態性的一個例子是在類型簽名Nothing
:
Nothing :: Maybe a
在類型可以是任何類型的可設想的a
,由於Nothing
棲息在所有Maybe
秒。我們說a
是參數多態,因爲它可以是任何類型。
現在考慮此類型:
Just 1 :: (Num b) => Maybe b
此番b
不能是任何類型的:它只能是一種類型,是Num
一個實例。我們說b
是ad-hoc多態的,因爲它可以是由類Num
的實例給出的一組類型中的任何成員。
因此,回顧一下:
參數多態:可以是任何類型
特設多態:由一種類約束
有三種類型你將經常遇到的多態性(使用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不同,它只是它的一個表達式。
當你說ML有亞型多態性時,你指的是OCaml嗎? – sepp2k 2013-04-28 20:17:48
如果你看看我提供的鏈接(http://www.haskell.org/haskellwiki/Haskell_Tutorial_for_C_Programmers),它似乎認爲'+'運算符是Haskell中「真多態性」的一個例子,其中在你的答案中,你用它來演示Ad-hoc多態性。我很困惑 – CodyBugstein 2013-04-28 20:32:10
在這篇文章的情況下,它是說C不支持任何類型的多態。如果你將「真正的多態性」理解爲「任何類型的多態性」,它會更有意義。 – 2013-04-28 22:10:47
維基百科文章中沒有提到「真正的多態性」。 – delnan 2013-04-28 17:02:02
@delnan你說得對,我很抱歉。我使用那篇文章來幫助我理解一般多態性的不同類型 – CodyBugstein 2013-04-28 20:13:14