模板 Haskell:为具有类型 class 约束的函数签名生成代码
Template Haskell: generating code for a function signature with the type class constraints
我需要为具有类型 class 约束的函数签名生成代码,例如:
fun :: (Ord a) => a -> a
我正在使用以下签名构造函数:
SigD Name Type
所以,我需要生成一个类型。我最好的猜测是使用以下构造函数:
ForallT [TyVarBndr] Cxt Type
它对应于以下声明(见Temaplate Haskell documentation):
forall <vars>. <ctxt> => <type>
但是 Cxt
只是 Type
列表的同义词,我找不到合适的 Type
构造函数来生成类型 class 约束。我应该怎么做才能为类型 class 约束生成代码?
我相信,正如评论中提到的,TH 没有区分 Type
s 和 Constraint
s(哪一种是有道理的,尤其是现在 ConstraintKinds
左右)。我通常发现,在使用 TH 生成代码时,检查准引用的 AST 是否有一个具体的、具体的例子,无论我试图实现什么,准引用都不够好。例如,在 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
for Ord
应用于您用于类型变量的名称。请注意,至少在这个级别,ForallT
参数列表是空的,因为类型签名中的 a
没有写成显式的 forall a.
.
我需要为具有类型 class 约束的函数签名生成代码,例如:
fun :: (Ord a) => a -> a
我正在使用以下签名构造函数:
SigD Name Type
所以,我需要生成一个类型。我最好的猜测是使用以下构造函数:
ForallT [TyVarBndr] Cxt Type
它对应于以下声明(见Temaplate Haskell documentation):
forall <vars>. <ctxt> => <type>
但是 Cxt
只是 Type
列表的同义词,我找不到合适的 Type
构造函数来生成类型 class 约束。我应该怎么做才能为类型 class 约束生成代码?
我相信,正如评论中提到的,TH 没有区分 Type
s 和 Constraint
s(哪一种是有道理的,尤其是现在 ConstraintKinds
左右)。我通常发现,在使用 TH 生成代码时,检查准引用的 AST 是否有一个具体的、具体的例子,无论我试图实现什么,准引用都不够好。例如,在 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
for Ord
应用于您用于类型变量的名称。请注意,至少在这个级别,ForallT
参数列表是空的,因为类型签名中的 a
没有写成显式的 forall a.
.