首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取模块导出的内容的列表。

获取模块导出的内容的列表。
EN

Stack Overflow用户
提问于 2019-10-16 15:55:36
回答 2查看 417关注 0票数 2

类似的问题(是否有办法在GHCI中查看模块中的函数列表?),虽然不是我所寻求的结果。

是否有方法获取模块导出的内容的列表?

当然,在GHCi中,您可以导入它,然后输入Some.Module.,点击选项卡进行自动完成,它将显示我想要的内容。但我想抓住那些东西。粗略地说,String -> [String]

目的?假设我有一个带有裸import Some.Module的源文件。问:该文件中的Some.Module属于什么?一个简单的方法是输出模块导出的内容列表,将其提供给grep并返回竞争者,而无需在GHCi中加载该源文件(可能是复杂的,也可能是不可能的)。一切都变得更清晰了。

如果有更聪明的方法,我在听。我听说了解决办法涉及GOAlambdabot。不知道是否适用或如何利用这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-16 18:39:39

交互使用的一个特别简单的方法是:browse。加载一个访问适当包的ghci,然后

代码语言:javascript
复制
> :browse Some.Module
class Some.Module.Foo a where
  Some.Module.foo :: a -> a
  {-# MINIMAL foo #-}
Some.Module.bar :: Int

所有的限定都可以得到一些,特别是如果有许多在同一模块中定义的类型上操作的函数。为了减少杂乱,您可以首先将Some.Module纳入范围:

代码语言:javascript
复制
> :m + Some.Module
> :browse Some.Module
class Foo a where
  foo :: a -> a
  {-# MINIMAL foo #-}
bar :: Int
票数 2
EN

Stack Overflow用户

发布于 2019-10-16 18:06:19

正如注释中提到的@HTNW,如果您可以在实际文件上运行ghc,则可以使用-ddump-minimal-imports。否则,如果您想从另一个模块获得导出列表,假设您使用的是GHC,那么最简单的方法可能是查看.hi 接口文件。一旦您知道接口文件的路径,ghc就支持打印接口文件的人类可读的表示,但是正如wiki页面所指出的,“这种文本格式并不是专门为机器解析而设计的”。您还可以通过GHC访问您可能需要的信息。下面是这样做的一个小例子。

我们从执行IO的大量随机导入开始&从GHC开始:

代码语言:javascript
复制
import Control.Monad.IO.Class
import System.IO
import System.Environment

import GHC
import GHC.Paths (libdir)
import DynFlags
import Outputable
import Name
import Pretty (Mode(..))

随着官僚作风的消失,main一开始就启动了GHC Monad:

代码语言:javascript
复制
main :: IO ()
main = defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
  runGhc (Just libdir) $ do

实际上,我们没有生成任何代码,因此可以在hscTarget = HscNothing安装样板期间设置DynFlags

代码语言:javascript
复制
    dflags <- getSessionDynFlags
    let dflags' = dflags { hscTarget = HscNothing }
    setSessionDynFlags dflags'

这样我们就可以从包数据库中找到我们想要的模块(使用第一个命令行参数作为名称):

代码语言:javascript
复制
    mn <- head <$> (liftIO $ getArgs)
    m <- lookupModule (mkModuleName mn) Nothing

我们可以使用getModuleInfo获得模块信息结构:

代码语言:javascript
复制
    mmi <- getModuleInfo m
    case mmi of
      Nothing -> liftIO $ putStrLn "Could not find module interface"

如果我们找到了接口,我们所需要的一切都在modInfoExports中。如果我们需要更多,我们也可以得到实际的ModIface

代码语言:javascript
复制
      Just mi -> mapM_ (printExport dflags') (modInfoExports mi)

实际上,输出输出有点繁琐,因为它需要使用Name;一个简单的示例printExport可能只使用漂亮的打印函数,但这些功能更适合于打印人类可读的输出,而不是机器可读的输出:

代码语言:javascript
复制
printExport :: DynFlags -> Name -> Ghc ()
printExport dflags n =
  liftIO $ printSDocLn PageMode dflags stdout (defaultUserStyle dflags)
         $ pprNameUnqualified n
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58417342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档