如何使用`reify`来获取函数的声明? [英] How to get the declaration of a function using `reify`?

查看:137
本文介绍了如何使用`reify`来获取函数的声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

功能 reify 允许我查找有关给定名称的信息。对于函数,返回的值是 VarI

 数据信息= ... | VarI名称类型(也许Dec)Fixity | ... 

在这里我可以检查函数的类型,我也想检查它的声明。然而,在 VarI 的第三个参数中,我总是看到 Nothing 。有没有办法获得函数的声明?

解决方案

模板haskell在VarI Info构造器上的文档


value变量(与类型变量相反,请参阅 TyVarI )。
Maybe Dec 字段包含 Just 定义变量的声明 - 包括声明的RHS - 或者在编译器不可用的情况下, Nothing 。目前,这个值始终是 Nothing :由于缺乏兴趣,返回RHS尚未实现。


查看 github上的ghc源代码镜像 string VarI 只出现两次,无论是在编译器/ typecheck / TcSplice.lhs 实施 reifyThing 函数:

  reifyThing :: TcTyThing  - > TcM TH.Info 
- 这是monadic的唯一原因是错误报告,
- 而这主要是针对TH不能表达
的情况 - 一些随机GHC扩展

reifyThing(AGlobal(AnId id))
= do {ty < - reifyType(idType id)
;修复< - reifyFixity(idName id)
;让v = reifyName id
; case idDetails id
ClassOpId cls - >返回(TH.ClassOpI v ty(reifyName cls)修复)
_ - > return(TH.VarI v ty Nothing fix)
}

reifyThing(AGlobal(ATyCon tc))= reifyTyCon tc
reifyThing(AGlobal(ADataCon dc))
= do {let name = dataConName dc
; ty < - reifyType(idType(dataConWrapId dc))
;修复< - reifyFixity名称
; return(TH.DataConI(reifyName name)ty
(reifyName(dataConOrigTyCon dc))fix)
}

reifyThing(ATcId {tct_id = id})
= do {ty1 < - zonkTcType(idType id) - 利用我们所有的信息,甚至
- 虽然它可能不完整
; ty2< - reifyType ty1
;修复< - reifyFixity(idName id)
; return(TH.VarI(reifyName id)ty2 Nothing fix)}

reifyThing(ATyVar tv tv1)
= do {ty1 < - zonkTcTyVar tv1
; ty2< - reifyType ty1
; return(TH.TyVarI(reifyName tv)ty2)}

reifyThing thing = pprPanicreifyThing(pprTcTyThingCategory thing)

就像模板haskell文档所说的那样,用于该字段的值总是 Nothing



挖掘更便宜,此代码于2003年添加,看起来像是重写reify系统。所以它似乎对获得它的工作没什么兴趣,因为它已经超过10年了,该领域一直具有 Nothing 的值。所以我猜你是否想要自己实现的功能(或者向ghc开发邮件列表提出一个很好的用例来鼓励别人去做)。

Function reify allows me to look up information about a given name. For a function the returned value is VarI:

data Info = ... |  VarI Name Type (Maybe Dec) Fixity  | ...

Here I can examine the function's type, and I'd also like to examine its declaration. However, in the 3rd argument to VarI I always see Nothing. Is there a way to get the function's declaration?

解决方案

From the template haskell docs on the VarI Info contructor:

A "value" variable (as opposed to a type variable, see TyVarI). The Maybe Dec field contains Just the declaration which defined the variable -- including the RHS of the declaration -- or else Nothing, in the case where the RHS is unavailable to the compiler. At present, this value is always Nothing: returning the RHS has not yet been implemented because of lack of interest.

Looking at the ghc source mirror on github, the string VarI only appears twice, and both in the compiler/typecheck/TcSplice.lhs implementing the reifyThing function:

reifyThing :: TcTyThing -> TcM TH.Info
-- The only reason this is monadic is for error reporting,
-- which in turn is mainly for the case when TH can't express
-- some random GHC extension

reifyThing (AGlobal (AnId id))
  = do  { ty <- reifyType (idType id)
        ; fix <- reifyFixity (idName id)
        ; let v = reifyName id
        ; case idDetails id of
            ClassOpId cls -> return (TH.ClassOpI v ty (reifyName cls) fix)
            _             -> return (TH.VarI     v ty Nothing fix)
    }

reifyThing (AGlobal (ATyCon tc))   = reifyTyCon tc
reifyThing (AGlobal (ADataCon dc))
  = do  { let name = dataConName dc
        ; ty <- reifyType (idType (dataConWrapId dc))
        ; fix <- reifyFixity name
        ; return (TH.DataConI (reifyName name) ty
                              (reifyName (dataConOrigTyCon dc)) fix)
        }

reifyThing (ATcId {tct_id = id})
  = do  { ty1 <- zonkTcType (idType id) -- Make use of all the info we have, even
                                        -- though it may be incomplete
        ; ty2 <- reifyType ty1
        ; fix <- reifyFixity (idName id)
        ; return (TH.VarI (reifyName id) ty2 Nothing fix) }

reifyThing (ATyVar tv tv1)
  = do { ty1 <- zonkTcTyVar tv1
       ; ty2 <- reifyType ty1
       ; return (TH.TyVarI (reifyName tv) ty2) }

reifyThing thing = pprPanic "reifyThing" (pprTcTyThingCategory thing)

Like the template haskell docs said, the value used for that field is always Nothing.

Digging deaper, this code was added in 2003, in what looks like a rewrite of the reify system. So it does appear to be little interest in getting it working since it has been more than 10 years that field has always had the value Nothing. So I'm guessing if you want the feature you will have to implement it yourself (or propose a good use case to the ghc development mailing list that would encourage someone else to do it).

这篇关于如何使用`reify`来获取函数的声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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