2013-02-07 14 views
13

ich habe dieseWie schreibe ich eine ableitbare Klasse?

data Something = Something Integer deriving (MyClass, Show) 

class MyClass a where 
    hello :: MyClass a => a -> a 

instance MyClass Integer where 
    hello i = i + 1 

main = print . hello $ Something 3 

aber MyClass ist nicht ableitbar. Warum?

+6

Sie brauchen nicht den 'MyClass a =>' Teil der Typ-Signatur für 'Hallo'; es wird dadurch impliziert, dass "a" über eine Klassendeklaration der Form "class MyClass a where ..." in den Geltungsbereich gebracht wird. –

+0

Werfen Sie einen Blick auf den [GHC-Benutzerleitfaden zum Ableiten] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extensions-to-the-deriving-mechanism). –

Antwort

13

GHC kann Instanzen für beliebige Datentypen nicht magisch ableiten. Jedoch kann die Tatsache nutzen, dass newtype Deklarationen einen neuen Namen für den gleichen zugrunde liegenden Typ erstellen, um Instanzen für diejenigen ableiten, die die GeneralizedNewtypeDeriving Erweiterung verwenden. So konnten Sie so etwas tun:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype Something = Something Integer deriving (MyClass, Show) 

class MyClass a where 
    hello :: MyClass a => a -> a 

instance MyClass Integer where 
    hello i = i + 1 

main = print . hello $ Something 3 

Der Grund GHC nicht die neue Instanz ableiten kann, ist, dass sie nicht weiß, was die Instanz sein sollte. Auch wenn Ihr Datentyp nur ein Feld enthält, ist es möglicherweise nicht unbedingt das selbe wie das Feld. Die Möglichkeit, Instanzen für newtype s abzuleiten, ist praktisch, da sie normalerweise verwenden, um unterschiedliche Verhaltensweisen für bestimmte Klassen bereitzustellen oder das Typsystem zu verwenden, um Dinge zu trennen, die denselben Typ, aber unterschiedliche Verwendungen in Ihrem Code haben.

+2

'newtype' Ableiten ist mit seiner aktuellen Implementierung zwar übersichtlich, aber nicht sicher. Ich sage nur in frühen Versionen deines Codes. Das neue 'default'/generische Framework ist allgemeiner und sicherer (aber auch clunkier), also benutze es wenn möglich. –

+0

@PhilipJF Das ist gut zu wissen. – sabauma

+0

@PhilipJF was ist unsicher über die aktuelle Implementierung von newtype abgeleitet? –

13

Vielleicht möchten Sie sich die GHC documentation on Generic Programming ansehen.
Sie müssen eine Klasse erstellen, die an einer generischen Darstellung beliebiger Typen arbeiten kann. Ich denke nicht, dass das spezifische Beispiel, das Sie gegeben haben, für eine ableitbare Klasse angemessen ist.

+2

+1 Froh, dass jemand diese Frage als Antwort auf diese Frage gestellt hat. Hast du Lust, dich in ein Beispiel zu verwandeln, wo es vernünftig ist? – AndrewC

+0

@AndrewC leider verstehe ich es nicht gut genug, um so weit zu erweitern. Wenn Sie die Frage frei editieren können. – asm

+0

Hier ist ein Beispiel für eine generische "Default" -Klasse (ein Typ ist standardmäßig das erste Konstrukt): http://pastebin.com/amgQRvFD (Ich lerne generische Programmierung selbst, ich weiß nicht, ob dies die beste ist Weg) –

Verwandte Themen