2014-11-01 77 views
14

我剛開始學習Haskell。我已經看過很多介紹類型基礎知識的介紹性例子,但它們通常在類型下面有一個deriving語句。下面是Chapter 3 of RealWorldHaskell一個例子:Haskell中的`derivation`引發了什麼?

data Cartesian2D = Cartesian2D Double Double 
        deriving (Eq, Show) 

data Polar2D = Polar2D Double Double 
       deriving (Eq, Show) 

他們解釋Chapter 6有所獲得,它可以幫助你知道如何使用它。

到目前爲止,據我所知,deriving (Show)有必要告訴Haskell如何將您的類型轉換爲字符串。這在實踐層面上是有道理的。我來自JavaScript的土地,所以對我來說,你可以很容易想象,這將等來實現:

Polar2D.prototype.toString = function(){ 
    return '[Polar2D]'; 
}; 

在Haskell,他們給出瞭如何實現自己的ShowColor型,而是採用deriving的例子。

data Color = Red | Green | Blue 
instance Show Color where 
    Red = "red" 
    Green = "green" 
    Blue = "blue" 

這意味着,當你在ghci REPL,你可以這樣做:

> show Red 
"red" 

但是,這並不能說明什麼deriving究竟是幹什麼,它仍然是魔術給我。

我的問題是,deriving引擎蓋下發生了什麼?另外,Haskell源代碼中的GitHub中有沒有可以看到實現的地方?這也可能有幫助。

回答

16

GHC實際上只是編寫您手動編寫的同一個實例,如果您將-ddump-deriv傳遞給編譯器,您可以看到它生成的代碼。例如:

Prelude> data Color = Red | Green | Blue deriving (Show) 

==================== Derived instances ==================== 
Derived instances: 
    instance Show Color where 
    showsPrec _ Red = showString "Red" 
    showsPrec _ Green = showString "Green" 
    showsPrec _ Blue = showString "Blue" 
    showList = showList__ (showsPrec 0) 


Generic representation: 

    Generated datatypes for meta-information: 

    Representation types: 

有沒有真正大的魔力怎麼回事,只是Show有一個非常機械的實現。在它裏面看看數據構造函數的內部形式(類型是GHC源代碼中的DataConRep),它從翻譯前端AST獲得,然後查看前端源中提供的名稱,並根據這些名稱添加新的Show實例以及任何也實現Show的嵌套類型。新的自動生成的類型類就像手寫代碼類一樣被註冊,就像它被寫入當前模塊一樣。

+0

這是真的,但有些奇怪的東西可能會發生(雖然我不是GHC的專家)。像[GeneralizedNewTypeDeriving] [1]一樣,它不會生成任何實例,但可以安全地重用內部類型的實例。 [2]與'DeriveDataTypeable',你不能寫一個手動的'Typeable'實例。 – 2015-09-26 23:40:24

相關問題