开发者

How to examine a quoted data constructor name in Template Haskell?

开发者 https://www.devze.com 2023-03-31 08:28 出处:网络
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:

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]) ( normal开发者_如何学编程B [| 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 |] ) [] 
                     ]
0

精彩评论

暂无评论...
验证码 换一张
取 消