2012-05-09 33 views

回答

3

我可以看到代數數據類型和麪向對象類風格類之間的三個主要區別,不包括(im)可變性因爲它有所不同。

  • 代數數據類型允許總和以及產品,而OO風格的類只允許產品。
  • OO風格的類允許您將複雜的數據項與其接受的操作捆綁在一起,而代數數據類型則不然。
  • 代數數據類型不區分傳遞給構造函數的數據和存儲在結果值中的數據,而OO風格的類可以(或可以))。

我故意忽略的一件事是子類型。儘管絕大多數面嚮對象語言允許您繼承(非最終的,非密封的,當前可訪問的)類,並且絕大多數通用ML家族函數式語言不支持,但顯然可以完全禁止假設繼承OO(或至少類OO)語言,同樣可以在代數數據類型中生成子類型和超類型;後者的有限的示例,請參閱this page on O'Haskell,已成功通過Timber

+1

所以ADT不需要*關閉*? Haskell的抽象數據類型不允許子類型(通過http://blog.tmorris.net/algebraic-data-types-again/) – canadadry

+0

@BonAmi不,抽象數據類型並不需要關閉。正如你所指出的,Haskell的是,但斯卡拉當然不一定(如果你可以稱爲案例類ADTs)。 –

3

類是不僅僅是一個類型定義更多 - 在大多數面嚮對象語言類實際上是提供各種鬆散的相關功能廚房水槽的功能。

特別是,類作爲一種模塊,爲您提供數據抽象和命名空間。代數數據類型沒有內置,模塊化通常作爲獨立的正交特徵(通常是模塊)提供。

3

在某種意義上,人們可以這樣看待它。每種語言都有很多機制來創建用戶定義的類型。在功能性(ML,Haskell風格)語言中,唯一一個是創建ADT。 (Haskell的新類型可以被看作ADT的退化情況)。在OO語言中,它是類。在程序語言中,它是structrecord

毫無疑問,用戶定義的數據類型的語義因語言而異,在範式#1中的語言和範式#2中的語言都不盡相同。 @ Pharien's Flame已經概述了典型的差異。

8

Algebraic data types如此命名是因爲它們形成「初始代數」,

+ represents sum types (disjoint unions, e.g. Either). 
• represents product types (e.g. structs or tuples) 
X for the singleton type (e.g. data X a = X a) 
1 for the unit type() 
and μ for the least fixed point (e.g. recursive types), usually implicit. 

從這些運營商的所有常規數據類型可以構造。 代數數據類型也支持參數化多義性 - 意味着它們可以用作任何基礎類型的常量,並具有靜態安全性保證。此外,ADT提供統一的語法來引入和消除數據類型(通過構造函數和模式匹配)。例如。

-- this defines a tree 
data Tree a = Empty | Node a (Tree a) (Tree a) 

-- this constructs a tree 
let x = Node 1 (Node 2 Empty) Empty 

-- this deconstructs a tree 
f (Node a l r) = a + (f l) + (f r) 

代數數據類型的豐富性和均勻性,與它們是不可變的事實一起,從OO對象區別開來,這在很大程度上:

  • 僅代表產品類型(所以沒有遞歸或總和-types)
  • 不支持的模式匹配
  • 是可變
  • 不支持參數多態性
+0

嗯。不是繼承類加法類型的子類? (所以一個類基本上是一個開放的總和?)我也看不出參數多態如何與代數數據類型相關聯。當然,你可以通過其他類型對它們進行參數化,但是你能不能用類來做呢?類型遞歸通常也適用,對吧? –

+0

是的,有足夠的擴展,你可以到那裏:「仿製藥,子類的組合,和虛擬調度支持denition和對象 - 面向對象編程語言的有限使用廣義代數的數據類型」 - http://research.microsoft。 COM/EN-US/UM /人/ akenn /仿製藥/ gadtoop.pdf –