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不能工作,除了手动列出关联类型同义词之外,还有其他解决方法吗?

这个问题出现在GHC 7.8.3版本2.9.0.0的template-haskell包中;它也出现在GHC 7.4.2的2.7.0.0版template-haskell包中。(我没有检查GHC 7.6。*,但我想它也出现在那里。)我对任何版本的GHC的解决方案感兴趣(包括“这只在GHC版本V中被修复”)。


当前回答

没有实现它是因为没有人请求它。

奇怪的是TH使用自己的AST,它不遵循内部编译器的AST。因此,任何新特性(例如关联类型族)都不能通过TH自动获得。总得有人开一张票来执行它。

供参考:内部reifyClass函数忽略相关的类型族(它是classsextrabigsig返回的元组的第5个元素,请参阅ClassATItem的定义。)

从技术上讲,在reify中实现关联类型族支持应该很容易,但很可能需要在TH API中进行向后不兼容的更改,例如,因为它的AST似乎不支持关联类型默认值。

现在已经实现了(顺便说一句,没有修改API),可能会在下一个ghc版本中使用。

其他回答

没有实现它是因为没有人请求它。

奇怪的是TH使用自己的AST,它不遵循内部编译器的AST。因此,任何新特性(例如关联类型族)都不能通过TH自动获得。总得有人开一张票来执行它。

供参考:内部reifyClass函数忽略相关的类型族(它是classsextrabigsig返回的元组的第5个元素,请参阅ClassATItem的定义。)

从技术上讲,在reify中实现关联类型族支持应该很容易,但很可能需要在TH API中进行向后不兼容的更改,例如,因为它的AST似乎不支持关联类型默认值。

现在已经实现了(顺便说一句,没有修改API),可能会在下一个ghc版本中使用。