如何检查模板Haskell中的引用数据构造函数名称? [英] How to examine a quoted data constructor name in Template Haskell?
问题描述
isLeft
和 isRight
(灵感来自这个问题)。这是我谦虚的尝试: isA connam = do
ConE nam < - connam
nn< - newNamep
lamE [varP nn] $ caseE(varE nn)[
match(conP nam [wildP])(normalB [| True |])[],
匹配wildP (normalB [| False |])[]
]
问题是,与单参数构造函数一起工作。罪魁祸首是 conP nam [wildP]
模式。理想情况下,它应该看起来像 conP nam(replicate(numArgs nam)wildP)
,其中 numArgs
是一个返回构造函数的参数个数。但是,我怎么写这样的功能呢?我想我需要访问相关的数据声明,但我不知道如何去做。
还有一个关于这个函数的问题。
href =http://hackage.haskell.org/packages/archive/template-haskell/2.6.0.0/doc/html/Language-Haskell-TH.html#v:reify =noreferrer> reify
并检查该类型以确定数据构造函数的arity,使用记录模式生成与arity无关的代码更容易: isFoo :: Bar - > Bool
isFoo p =
(Foo {}) - >的案例p True - 无论Foo的价值是多少
_ - >都是有效的。假
这可以通过替换 conP
在代码中使用 recP
。
isA connam = do
conE nam < - connam
nn< - newNamep
lamE [varP nn] $ caseE(varE nn)[
match(recP nam [])(normalB [| True |])[],
匹配wildP(normalB [| False |])[]
]
I'm trying to learn some Template Haskell. As an exercise, I wrote a function that can generate things like isLeft
and isRight
(inspired by this question). Here's my humble attempt:
isA connam = do
ConE nam <- connam
nn <- newName "p"
lamE [varP nn] $ caseE (varE nn) [
match (conP nam [wildP]) ( normalB [| True |] ) [],
match wildP ( normalB [| False |] ) []
]
The problem is that it only works with one-argument constructors. The culprit is the conP nam [wildP]
pattern. Ideally, it should look like conP nam (replicate (numArgs nam) wildP)
, where numArgs
is a function returning the number of arguments of the constructor. But how do I write such a function? I imagine I need to access the relevant data declaration, but I have no idea how to.
There is another question about this very same function here.
While you could use reify
and examine the type to determine the arity of the data constructor, it's much easier to generate arity-independent code using a record pattern:
isFoo :: Bar -> Bool
isFoo p = case p of
(Foo {}) -> True -- Valid no matter what the arity of Foo is
_ -> False
This can be done by replacing conP
with recP
in your code.
isA connam = do
ConE nam <- connam
nn <- newName "p"
lamE [varP nn] $ caseE (varE nn) [
match (recP nam []) ( normalB [| True |] ) [],
match wildP ( normalB [| False |] ) []
]
这篇关于如何检查模板Haskell中的引用数据构造函数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!