it-swarm.com.de

Assoziierte Typ-Synonyme mit Vorlage Haskell erhalten

Kann Template Haskell die Namen und/oder Deklarationen der in einer Typenklasse deklarierten zugehörigen Typensynonyme herausfinden? Ich habe erwartet, dass reify tun würde, was ich will, aber es scheint nicht alle notwendigen Informationen zu liefern. Es funktioniert für das Abrufen von Funktionssignaturen:

% ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
...
Prelude> -- I'll be inserting line breaks and whitespace for clarity
Prelude> -- in all GHCi output.
Prelude> :set -XTemplateHaskell 
Prelude> import Language.Haskell.TH
Prelude Language.Haskell.TH> class C a where f :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C)
ClassI (ClassD [] Ghci1.C [PlainTV a_1627398388] []
               [SigD Ghci1.f
                     (ForallT [PlainTV a_1627398388]
                              [ClassP Ghci1.C [VarT a_1627398388]]
                              (AppT (AppT ArrowT (VarT a_1627398388))
                                    (ConT GHC.Types.Int)))])
       []

Wenn Sie der Klasse jedoch ein zugeordnetes Typensynonym hinzufügen, wird die Ausgabe bis zur Umbenennung nicht geändert:

Prelude Language.Haskell.TH> :set -XTypeFamilies 
Prelude Language.Haskell.TH> class C' a where type F a :: * ; f' :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       []

Wenn ich den Namen von F kenne, kann ich Informationen darüber nachschlagen:

Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
                 Ghci3.F
                 [PlainTV a_1627405973]
                 (Just StarT))
        []

Aber ich kann den Namen von F überhaupt nicht finden. Selbst wenn ich eine Instanz der Typklasse hinzufüge, enthält InstanceD keine Informationen zur Definition:

Prelude Language.Haskell.TH> instance C' [a] where type F [a] = a ; f' = length
Prelude Language.Haskell.TH> f' "Haskell"
7
Prelude Language.Haskell.TH> 42 :: F [Integer]
42
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       [InstanceD []
                  (AppT (ConT Ghci3.C')
                        (AppT ListT (VarT a_1627406161)))
                  []]

Wenn reify nicht funktioniert, gibt es eine andere Problemumgehung als die manuelle Auflistung der Synonyme für den verknüpften Typ?

Dieses Problem tritt in GHC 7.8.3 mit Version 2.9.0.0 des Pakets template-haskell auf. es war auch in GHC 7.4.2 mit Version 2.7.0.0 des template-haskell-Pakets vorhanden. (Ich habe GHC 7.6. * Nicht überprüft, aber ich stelle mir vor, dass es auch dort vorhanden war.) Ich interessiere mich für Lösungen für jede Version von GHC (einschließlich "Dies wurde nur in der GHC-Version behoben [~ # ~] v [~ # ~] ").

254

Es wird nicht implementiert, weil es niemand angefordert hat.

Das Seltsame ist, dass TH verwendet sein eigenes AST, das nicht dem AST des internen Compilers folgt. Daher ist jedes neue Feature (z. B. zugeordnete Typfamilien) nicht automatisch über TH verfügbar man muss ein Ticket öffnen und implementieren.

Als Referenz: interne reifyClass -Funktion ignoriert zugeordnete Typfamilien (es ist das 5. Element des Tupels, das von classExtraBigSig zurückgegeben wird, siehe auch Definition von ClassATItem .)

Technisch sollte es einfach sein, die Unterstützung für zugehörige Typenfamilien in reify zu implementieren, höchstwahrscheinlich sind jedoch rückwärts inkompatible Änderungen in TH API erforderlich, z. B. weil AST unterstützt anscheinend keine zugehörigen Standardtypen.

Hinzugefügt: Es ist jetzt implementiert (ohne API-Änderung übrigens) und wird wahrscheinlich in der nächsten ghc Freisetzung.

13
Yuras