Template Haskell, bir tür sınıfında bildirilen ilişkili tür eş anlamlılarının adlarını ve / veya bildirimlerini bulabilir mi? İstediğimi reify
yapmayı bekliyordum , ancak gerekli tüm bilgileri sağlamıyor gibi görünüyor. İşlev tipi imzaları almak için çalışır:
% 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)))])
[]
Ancak, sınıfa ilişkilendirilmiş bir tür eşanlamlısı eklemek çıktıda hiçbir değişikliğe (yeniden adlandırmaya kadar) neden olmaz:
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)))])
[]
Adını biliyorsanız, F
bunun hakkında bilgi arayabilirim:
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
Ghci3.F
[PlainTV a_1627405973]
(Just StarT))
[]
Ama F
ilk etapta adını bulamıyorum . Type sınıfının bir örneğini eklesem bile InstanceD
, tanımı hakkında hiçbir bilgi yoktur:
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)))
[]]
Eğer reify
iş olmaz, bir geçici çözüm elle ilişkilendirmek tip eş anlamlılarını listeleme dışında var mı?
Bu sorun, şablon haskell paketinin 2.9.0.0 sürümü ile GHC 7.8.3'te bulunmaktadır; GHC 7.4.2'de template-haskell paketinin 2.7.0.0 sürümü ile mevcuttu. (GHC 7.6. * 'Da kontrol etmedim, ama orada da var olduğunu hayal ediyorum.) GHC'nin herhangi bir sürümü için çözümlerle ilgileniyorum ("bu sadece GHC V sürümünde düzeltildi " dahil).
InstanceD
gördüğümle aynı şeyleri doğurur reify
: putStrLn $(stringE . show =<< reifyInstances ''C' =<< sequence [[t|[Int]|]])
değerlendirir [InstanceD [] (AppT (ConT Ghci1.C') (AppT ListT (VarT a_1627405978))) []]
, tip aile örneklerinden yoksundur.
reify
Gerekli bilgileri döndürmeyen garip buluyorum . Belki de show
bazı bilgiler saklanıyor? Info
Nesneyi doğrudan incelemeyi denediniz mi?
Info
'in Show
örnek sadece bir türetilmiştir ve aynı Show
-örneğin Dec
. Eğer istedi ve Ancak, ben de doğrudan kontrol edebilirsiniz, no: putStrLn $(reify ''C' >>= \i -> case i of ClassI (ClassD _ _ _ _ [SigD _ _]) _ -> stringE "just a SigD" ; _ -> stringE "something else")
üretir just a SigD
- ki gerçekten tek şey [Dec]
içinde ClassD
! (gerektirir LambdaCase
). Bunun garip olduğunu kabul ediyorum; bu yüzden bu soruyu sordum :-)
reifyInstances
?