2012-11-11 3 views

Antwort

10

Ja, Multiparameter-Klassen werden unterstützt.

Etwas verwirrend, das Type Argument bezieht sich auf die gesamte Instanz Kopf, und, auch wenn es sich um eine Art nicht wirklich vor sich, es genug sieht aus wie ein syntaktisch, dass der Typ Type für diesen Zweck wiederverwendet wurde.

Deshalb, wenn Sie einen Multi-Parameter-instance Foo Int Bool zu erzeugen, müssen Sie den "Typ" verwenden Foo Int Bool, beispielsweise wie folgt aufgebaut:

(ConT (mkName "Foo") `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool") 

Hier ist ein komplettes Beispiel:

{-# LANGUAGE MultiParamTypeClasses, TemplateHaskell #-} 

import Language.Haskell.TH 

class Foo a b where 
    foo :: (a, b) 

$(return [InstanceD [] (((ConT (mkName "Foo")) `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool")) 
    [ValD (VarP (mkName "foo")) 
     (NormalB (TupE [LitE (IntegerL 42), ConE (mkName "False")])) []]]) 

main = print (foo :: (Int, Bool)) 
6

Eine einfache Möglichkeit, dies zu beantworten, ist die Verwendung von runQ mit gespleißten Definitionen. ZB in GHCI:

$ ghci 
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help 
Prelude> :set -XTemplateHaskell 
Prelude> :set -XMultiParamTypeClasses 
Prelude> import Language.Haskell.TH 
Prelude Language.Haskell.TH> class Class a b where 
Prelude Language.Haskell.TH> runQ [d| instance Class Int Bool where |] 
[InstanceD [] (AppT (AppT (ConT :Interactive.Class) (ConT GHC.Types.Int)) (ConT GHC.Types.Bool)) []] 

Dies zeigt die genaue Form benötigt wird, ersetzen Class mit dem, was Klasse Sie verwenden.

Verwandte Themen