获取与模板Haskell关联的类型同义词

获取与模板Haskell关联的类型同义词,haskell,template-haskell,type-families,reify,associated-types,Haskell,Template Haskell,Type Families,Reify,Associated Types,Template Haskell能否找到类型类中声明的关联类型同义词的名称和/或声明?我原以为你会做我想做的,但它似乎没有提供所有必要的信息。它用于获取函数类型签名: % 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

Template Haskell能否找到类型类中声明的关联类型同义词的名称和/或声明?我原以为你会做我想做的,但它似乎没有提供所有必要的信息。它用于获取函数类型签名:

% 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)))])
       []
但是我首先找不到
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)))
                  []]
Prelude Language.Haskell.TH>实例C'[a],其中类型F[a]=a;f'=长度
前奏曲语言.Haskell.TH>f'“Haskell”
7.
前奏曲语言.Haskell.TH>42::F[整数]
42

Prelude Language.Haskell.TH>putStrLn$(stringE.show=没有实现,因为没有人请求它

奇怪的是TH使用自己的AST,它不遵循内部编译器的AST。因此,任何新功能(例如关联的类型族)都不能通过TH自动使用。有些人必须打开一个票证并实现它

参考:internal
reifyClass
函数关联类型族(它是返回的元组的第5个元素,另请参见的定义。)

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


添加:它现在(顺便说一句,没有API更改)可能会在下一个
ghc
版本中提供。

你看过
reifyInstances
了吗?@kwartz:我现在刚试过。但是它不起作用;它只是产生了与
reify
putStrLn相同的
实例$(stringE.show=我觉得奇怪的是,
reify
没有返回必要的信息。也许
show
隐藏了一些信息?您是否尝试过直接检查
Info
对象?@kwartz:恐怕
Info
show
实例只是派生的一个,而
show
例如
Dec
。但是,我也可以直接检查,正如你所问,否:
putStrLn$(具体化'C'>=\I->ClassI的第一个案例(ClassD.\uuuuud.[SigD.\uuud]->stringE“只是一个SigD”;\uud->stringE“其他的东西”)
产生
只是一个SigD
——这是
[Dec]中唯一的东西
ClassD
!(需要
LambdaCase
)中。我同意这很奇怪;这就是我问这个问题的原因:-)@Abel:我想我们达成了激烈的一致——你最初的评论说这不足以吸引一个绝妙的想法,但它确实吸引了Yuras的答案!我完全同意好的答案是:-)@AntalS-Z我的意思是
FamilyD
不支持。您可能没有使用它们,但完整的解决方案可能需要更改API。@Abel,将悬赏保留到最后也有助于好答案吸引选票,因此奖励好答案比快速奖励好答案更有效。悬赏期已过。这是最好的方法(且仅限于)回答,直到或除非。在回答中包含错误报告的链接可能是个好主意。仅供参考,#10891已修复,正在等待合并。@SwiftsNames AFAIK ghc开发者希望在不破坏API的情况下自由更改内部AST。可能还有其他原因。
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
                 Ghci3.F
                 [PlainTV a_1627405973]
                 (Just StarT))
        []
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)))
                  []]