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

查看:90
本文介绍了如何检查模板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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆