260

Template Haskell は、型クラスで宣言された関連型シノニムの名前や宣言を見つけることができますか? reifyやりたいことができると思っていましたが、必要な情報がすべて提供されているようには見えません。関数型のシグネチャを取得するために機能します。

% 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)))])
       []

ただし、関連付けられた型シノニムをクラスに追加しても、出力は (名前の変更まで) 変更されません。

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)))])
       []

の名前が​​わかればF、それに関する情報を調べることができます。

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

Fしかし、そもそもの名前が見つかりません。型クラスのインスタンスを追加しInstanceDても、定義に関する情報はありません。

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)))
                  []]

うまくいかない場合reify、アソシエート タイプのシノニムを手動でリストする以外に回避策はありますか?

この問題は、template-haskell パッケージのバージョン 2.9.0.0 を含む GHC 7.8.3 に存在します。template-haskell パッケージのバージョン 2.7.0.0 を含む GHC 7.4.2 にも存在していました。(私は GHC 7.6.* をチェックしませんでしたが、そこにも存在していたと思います。) GHC の任意のバージョンのソリューションに興味があります (「これは GHC バージョンVでのみ修正されました」を含む)。

4

1 に答える 1

15

誰も要求しなかったため、実装されていません。

奇妙なことに、TH は内部コンパイラの AST に従わない独自の AST を使用します。その結果、新しい機能 (関連する型ファミリなど) は、TH を介して自動的に利用できるわけではありません。誰かがチケットを開いて実装する必要があります。

参考までに: 内部reifyClass関数は関連付けられた型ファミリを無視します(これは によって返されるタプルの 5 番目の要素です。classExtraBigSigの定義も参照してくださいClassATItem)。

技術的には、関連付けられた型ファミリのサポートを で実装するのは簡単なはずreifyですが、TH API で下位互換性のない変更が必要になる可能性が高くなります。たとえば、AST が関連付けられた型のデフォルトをサポートしていないように見えるためです。

追加:現在実装されており(ところで API の変更はありません)、おそらく次のghcリリースで利用できるようになるでしょう。

于 2015-09-17T10:34:47.217 に答える