2014-11-01 5 views
14

Ich fange gerade Haskell zu lernen. Ich habe viele Intro Beispiele erläutern die Grundlagen der Typen gesehen, aber sie haben oft eine deriving Erklärung unter dem Typ. Hier ist ein Beispiel von Chapter 3 of RealWorldHaskell:Was mit `deriving` in Haskell unter der Haube passiert?

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

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

Sie erklären Ableitung etwas in Chapter 6, was dazu beiträgt, Sie wissen, wie es verwendet wird.

So weit davon entfernt, was ich verstehe, ist deriving (Show) notwendig Haskell zu sagen, wie Sie Ihre Art in einen String zu drehen. Das ist praktisch sinnvoll. Ich komme aus JavaScript Land, so mir Sie dies leicht wie umgesetzt würde sich vorstellen kann:

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

In Haskell, sie geben das Beispiel dafür, wie Sie Ihre eigenen Show für die Color Art zu implementieren, anstatt deriving zu verwenden.

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

Das bedeutet, wenn Ihr in den ghci repl, können Sie tun:

> show Red 
"red" 

Aber das erklärt nicht, was deriving tatsächlich tun, ist es noch zu mir Magie.

Meine Frage ist, was mit deriving unter der Haube geschieht? Gibt es auch einen Platz auf GitHub in der Haskell-Quelle, wo Sie die Implementierung sehen können? Das kann auch hilfreich sein.

Antwort

16

GHC schreibt praktisch die selbe Instanz, die Sie selbst geschrieben haben. Wenn Sie -ddump-deriv an den Compiler übergeben, können Sie den erzeugten Code sehen. Zum Beispiel:

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: 

Es gibt nicht wirklich viel Magie denn hier los, Show hat nur eine sehr mechanische Umsetzung. Im Inneren wird die interne Form der Datenkonstruktoren betrachtet (der Typ ist DataConRep in der GHC-Quelle), die er aus der Übersetzung des Frontend AST erhält und dann die in der Frontend-Quelle bereitgestellten Namen betrachtet und eine neue Show-Instanz mit diesen Namen hinzufügt und alle verschachtelten Typen, die auch Show implementieren. Der neu automatisch generierte typeclass registriert ist wie eine Hand codierte Klasse, als ob es im aktuellen Modul geschrieben wurde.

+0

das stimmt hier, aber einige seltsame Sachen können passieren (obwohl ich kein Experte für GHC bin). wie [1] mit 'GeneralizedNewTypeDeriving' erzeugt es keine Instanzen, sondern verwendet die Instanzen der inneren Typen sicher wieder. auch [2] mit 'DerivateDataTypeable', können Sie keine manuelle' Typable' Instanz schreiben. –

Verwandte Themen