如何检查模板Haskell中的引用数据构造函数名称?(How to examine a quoted data constructor name in Template Haskell?)

编程入门 行业动态 更新时间:2024-10-27 01:31:47
如何检查模板Haskell中的引用数据构造函数名称?(How to examine a quoted data constructor name in Template Haskell?)

我正在尝试学习一些模板Haskell。 作为练习,我写了一个函数,可以生成诸如isLeft和isLeft东西(受此问题的启发)。 这是我谦虚的尝试:

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 |] ) [] ]

问题是它只适用于一个参数的构造函数。 罪魁祸首是conP nam [wildP]模式。 理想情况下,它应该看起来像conP nam (replicate (numArgs nam) wildP) ,其中numArgs是一个函数,返回构造函数的参数个数。 但是,我怎么写这样的功能呢? 我想我需要访问相关的数据声明,但我不知道如何。

这里还有一个关于这个相同功能的问题 。

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.

最满意答案

虽然您可以使用reify并检查类型以确定数据构造函数的arity,但使用记录模式生成与arity无关的代码要容易得多:

isFoo :: Bar -> Bool isFoo p = case p of (Foo {}) -> True -- Valid no matter what the arity of Foo is _ -> False

这可以通过用代码中的recP替换conP来完成。

isA connam = do ConE nam <- connam nn <- newName "p" lamE [varP nn] $ caseE (varE nn) [ match (recP nam []) ( normalB [| True |] ) [], match wildP ( normalB [| False |] ) [] ]

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 |] ) [] ]

更多推荐

本文发布于:2023-08-03 15:26:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1395119.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   模板   名称   数据   Haskell

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!