テンプレート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でのみ修正されました」を含む)の解決策に興味があります。
InstanceD
IのこぎりのようにS reify
:putStrLn $(stringE . show =<< reifyInstances ''C' =<< sequence [[t|[Int]|]])
と評価され[InstanceD [] (AppT (ConT Ghci1.C') (AppT ListT (VarT a_1627405978))) []]
、型族インスタンスを欠いています。
reify
必要な情報が返されないのは不思議です。おそらくshow
いくつかの情報を隠していますか?Info
オブジェクトを直接調べてみましたか?
Info
のShow
インスタンスは単なる派生であり、のShow
インスタンスも同じですDec
。あなたが聞くと、しかし、私も直接チェックすることができ、何ら:putStrLn $(reify ''C' >>= \i -> case i of ClassI (ClassD _ _ _ _ [SigD _ _]) _ -> stringE "just a SigD" ; _ -> stringE "something else")
発生しないjust a SigD
-それは本当に唯一のことだ[Dec]
でClassD
!(が必要ですLambdaCase
)。変だと思う。それが私がこの質問をした理由です:-)
reifyInstances
?