2
顯然,下面的類型定義是cyclic
:循環類型定義
type node = int * node;;
Error: The type abbreviation node is cyclic
我的問題是如何產生以下一個是not cyclic
?
type tree = Node of int * tree;;
第二個定義也指自己。
顯然,下面的類型定義是cyclic
:循環類型定義
type node = int * node;;
Error: The type abbreviation node is cyclic
我的問題是如何產生以下一個是not cyclic
?
type tree = Node of int * tree;;
第二個定義也指自己。
一種看待它的方法是node
是一種類型的縮寫,而不是新的類型本身。因此,編譯器(或任何感興趣的人)必須查看內部以查看它的縮寫。一旦進入內部,你會注意到難以分析的事物(例如,它是遞歸類型,因此可能需要許多展開)。
另一方面,tree
是一個新的類型,其特點是它的構造函數。 (在這種情況下,只有一個構造函數Node
)。所以編譯器(或其他感興趣的團體)根本不需要考慮內容以確定類型。一旦你看到Node
的類型確定。即使你看到裏面,你只需要向下看一個層次。這允許遞歸而不造成任何分析困難。
實際上,第一類的遞歸類型往往是無意的,它們會導致奇怪的類型。第二類實際上不可能由於小路標(構造函數)在一路上錯誤地創建;實際上它們有點像類型系統的命脈。
區別在於,在類型檢查時您不會冒險定義無限展開:必須應用構造函數'Node'來獲取類型'tree'以展開到'int * tree'。 – gallais
@gallais您能否將您的評論轉換爲更詳細的答案? –
請注意,您實際上可以使用'-ypeypes'選項來允許這種類型(這會禁用類型檢查/推斷機制的發生檢查)。 – phimuemue