我需要为类型为约束的函数签名生成代码,例如:
fun :: (Ord a) => a -> a
我正在使用以下签名构造函数:
SigD Name Type
所以,我需要生成一个类型。我最好的猜测是使用以下构造函数:
ForallT [TyVarBndr] Cxt Type
它对应于以下声明(如Temaplate Haskell documentation所示):
forall <vars>. <ctxt> => <type>
但是Cxt
只是Type
列表的同义词,我找不到Type
的适当构造函数来生成类型类约束。如何为类型类约束生成代码?
答案 0 :(得分:1)
我认为,正如评论中提到的那样,TH不会在Type
和Constraint
之间进行区分(这很有意义,尤其是现在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
。