2017-09-04 3 views
1

ich so abgeleitete Instanz verwenden möchten:Abgeleitet Beispiel in Haskell

data Test3D = forall a. (Show a, Eq a, Typeable a, Generic a) 
       => Test3D { testDt :: String 
          , testPrm :: a 
          } 
    deriving (Show, Eq, Typeable, Generic) 

instance Binary (Test3D) 
$(deriveJSON defaultOptions ''Test3D) 

Aber ich von GHC erhalten:

• Can't make a derived instance of ‘Show Test3D’: 
     Constructor ‘Test3D’ has existentials or constraints in its type 
     Possible fix: use a standalone deriving declaration instead 
• In the data declaration for ‘Test3D’ 

Auf diese Weise ist sehr praktisch für mein Projekt. Ich kann die Lösung nicht finden.

Kann eine abgeleitete Instanz für solche Daten verwendet werden?

+1

Wie würden Sie die Instanz selbst schreiben? Selbst das Schreiben der Typ-Signatur wird sich als schwierig erweisen, wenn Sie Informationen über das 'testPrm' anzeigen möchten. Wenn Sie nicht wissen, wie es geht, kann GHC das nicht automatisch für Sie tun. Auf der anderen Seite, wenn Sie "testPrm" nicht anzeigen möchten, ist die Instanz leicht von Hand zu schreiben und Sie müssen sie nicht ableiten. – amalloy

+1

Dies beinhaltet das Schreiben einer "Binary" -Instanz für jedes 'Generic'. Es sieht als eine ziemlich komplexe Aufgabe aus. Ich denke, wir können nicht realistisch hoffen, dass der Automagische Ableitungsmechanismus dies für uns gelöst hat. Vielleicht könnten wir eine einfachere Instanz manuell schreiben, wenn wir 'Binary a' anstelle von' Generic a' verwenden? – chi

+0

Vielleicht implementiere ich meine Idee nicht richtig. Ich möchte nur eine Art von Daten haben, die wiederum ein Feld mit einem unbekannten Typ enthält. Aber der Feldtyp erfüllt eine bestimmte Anforderung durch Typklassen. Und alle sollten (Show a, Eq a, Typable a, Generic, ...) sein. – QSpider

Antwort

5

Gibt es eine Möglichkeit, die abgeleitete Instanz für solche Daten zu verwenden?

Ja. Tun Sie, was GHC vorgeschlagen, machen Sie eine eigenständige Ableitung Klausel:

{-# LANGUAGE StandaloneDeriving, ExistentialQuantification #-} 

data Test3D = forall a. (Show a) 
       => Test3D { testDt :: String 
          , testPrm :: a 
          } 

deriving instance Show Test3D 

Was können Sie nicht tun, ist eine Eq Instanz ableiten, weil unterschiedliche Werte tatsächlich verschiedene Arten enthalten und es ist nur möglich, diese mit einem dynamischen Guss vergleichen hack durch Typeable.

Verwandte Themen