2013-02-11 107 views
6

在讀編譯運行管道的各個階段,type聲明和newtype聲明之間有什麼不同?類型和新類型之間的編譯時間和運行時間差

我的假設是,他們編譯成相同的機器指令,而唯一的區別是,當程序typechecked,其中,例如

type Name = String 
newtype Name_ = N String 

您可以使用一個Name任何地方String是必需的,但是如果您使用Name_(其中String是預期的,即使它們編碼了相同的信息),類型檢測器也會將您叫出來。

我問這個問題,因爲如果是這樣的話,我看不出有任何理由如下聲明不應該是有效的:

type List a = Either() (a, List a) 
newtype List_ a = L (Either() (a, List_ a)) 

然而,類型檢查器接受第二一但拒絕第一個。這是爲什麼?

+10

這不是一個編譯問題,它是一個類型檢查問題。 Haskell使用「iso-recursive types」而不是「equi-recursive types」,所以如果你希望你的類型是遞歸的,你必須在那裏有一個'data'或'newtype'。每種選擇都有各種各樣的權衡。請參閱Pierce的類型和編程語言以瞭解更多關於這些系統和涉及的選擇。 – luqui 2013-02-11 12:03:52

+2

謝謝,我想我只需要「iso-recursive」和「equi-recursive」這兩個名字就可以知道Google要做什麼!如果你想將其轉換爲答案,我會接受它。 – 2013-02-11 12:08:11

回答

4

Luqui的評論應該是一個答案。 Haskell中的類型同義詞首先近似於宏。也就是說,它們被類型檢查器擴展爲完全評估的類型。類型檢查器不能處理無限類型,所以Haskell不具有等遞歸類型。

newtypes爲您提供的iso-recursive類型,在GHC中,本質上是編譯爲核心語言中的等遞歸類型。 Haskell不是GHC核心,所以你不能訪問這些類型。 Equi遞歸類型對於類型檢查器和人類都有點難,而iso-recursive類型具有相同的功能。

+0

感謝Philip。我是否理解GHC Core具有等遞歸類型? 「newtype」標籤中的信息在什麼階段消失? – 2013-02-11 19:48:34

+0

我避免了像瘟疫一樣的核心,所以把我說的一切都說出來:GHC核心有iso-recursive類型。核心中不存在新類型。我的看法是,這可能會被未來使用類型等式約束所取代:所以'List_a =(或者()(a,r))〜r => r',並在每個用例中插入這些等式的證明(做這件事的機器已經存在)。 – 2013-02-11 19:55:31

+0

@PhilipJF:[這有點複雜](http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/FC#Newtypesarecoercedtypes)現在,newtypes可以編譯成數據類型和類型等式公理:'newtype T = MkT Int'產生axT:T〜Int'的公理。不幸的是,這是不健全的:如果我們有'鍵入家族F a;類型實例F Int = Bool;類型實例F T = Char',然後是'Bool_F Int','F Int_F T'和'F T_Char'。因此'Bool〜Char',我們遇到了麻煩。 [這實際上可以用'GeneralizedNewtypeDeriving'。](http://hackage.haskell.org/trac/ghc/ticket/1496) – 2013-02-12 06:08:02