模板Haskell:为类型类约束的函数签名生成代码

时间:2018-06-18 10:27:20

标签: haskell template-haskell

我需要为类型为约束的函数签名生成代码,例如:

fun :: (Ord a) => a -> a

我正在使用以下签名构造函数:

SigD Name Type 

所以,我需要生成一个类型。我最好的猜测是使用以下构造函数:

ForallT [TyVarBndr] Cxt Type

它对应于以下声明(如Temaplate Haskell documentation所示):

forall <vars>. <ctxt> => <type>

但是Cxt只是Type列表的同义词,我找不到Type的适当构造函数来生成类型类约束。如何为类型类约束生成代码?

1 个答案:

答案 0 :(得分:1)

我认为,正如评论中提到的那样,TH不会在TypeConstraint之间进行区分(这很有意义,尤其是现在ConstraintKinds是周围)。我通常会检查准AST的具体具体示例,以研究在试图用准生成器做不到的TH生成代码时试图实现的任何示例。例如,在GHCI中:

λ> :set -XTemplateHaskell
λ> import Language.Haskell.TH
λ> runQ $ [d|f :: Ord a => a -> a; f = id|]
[SigD f_1 (ForallT [] [AppT (ConT GHC.Classes.Ord) (VarT a_0)] (AppT (AppT ArrowT (VarT a_0)) (VarT a_0))),ValD (VarP f_1) (NormalB (VarE GHC.Base.id)) []]

这表明约束部分只是应用于类型变量名称的Name的{​​{1}}。请注意,至少在此级别上,Ord参数列表为空,因为类型签名中的ForallT未被写为显式a