haskell - 获取模块导出的列表
问题描述
类似的问题(有没有办法在 GHCI 中查看模块中的函数列表?),虽然不是我寻求的结果。
有没有办法获取模块导出的内容列表?
当然,在 GHCi 中,您可以导入它,然后键入Some.Module.
,点击选项卡以自动完成,它会显示我所寻找的内容。但我想捕捉那些东西。粗略地说,String -> [String]
.
目的?假设我有一个带有裸import Some.Module
. Some.Module
问题:该文件属于什么?一种简单的方法是输出模块导出的列表,将其提供给grep
并返回竞争者,而无需在 GHCi 中加载该源文件(可能很复杂或不可能)。一切都变得清晰了很多。
如果有更聪明的方法,我在听。我听说过涉及GOA
和的解决方案lambdabot
。不知道是否适用或如何利用它。
解决方案
正如@HTNW 在评论中提到的那样,如果您可以ghc
在实际文件上运行,则可以使用-ddump-minimal-imports
. 否则,如果您想实际获取另一个模块的导出列表,假设您正在使用 GHC,那么最简单的方法可能是查看.hi
接口文件。 ghc
一旦您知道了接口文件的路径,就有一些内置支持打印接口文件的人类可读表示,但正如 wiki 页面所指出的那样“这种文本格式不是专门为机器解析而设计的”。您还可以通过 GHC API 访问您可能需要的信息。下面是一个做类似事情的小例子。
我们从一堆随机导入开始,用于从 GHC api 执行 IO 和:
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:
main :: IO ()
main = defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
runGhc (Just libdir) $ do
我们实际上并没有生成任何代码,因此我们可以hscTarget = HscNothing
在DynFlags
设置样板中进行设置:
dflags <- getSessionDynFlags
let dflags' = dflags { hscTarget = HscNothing }
setSessionDynFlags dflags'
这样我们就可以从包数据库中找到我们想要的模块(使用第一个命令行参数作为名称):
mn <- head <$> (liftIO $ getArgs)
m <- lookupModule (mkModuleName mn) Nothing
我们可以getModuleInfo
用来获取模块信息结构:
mmi <- getModuleInfo m
case mmi of
Nothing -> liftIO $ putStrLn "Could not find module interface"
如果我们确实找到了接口,我们需要的一切都在modInfoExports
. 如果我们需要更多,我们还可以获得实际的ModIface
:
Just mi -> mapM_ (printExport dflags') (modInfoExports mi)
实际上打印输出有点乏味,因为它需要使用Name
s; 一个简单的例子printExport
可能只使用了漂亮的打印功能,但这些功能更多地用于打印人类可读的输出而不是机器可读的输出:
printExport :: DynFlags -> Name -> Ghc ()
printExport dflags n =
liftIO $ printSDocLn PageMode dflags stdout (defaultUserStyle dflags)
$ pprNameUnqualified n
推荐阅读
- ruby-on-rails - has_and_belongs_to_many 关联是否可以包含“所有者”?
- c# - MessageLockLostException 中断服务总线 QueueClient
- nginx - 当响应从 memcached 上游发送时,为什么 nginx $upstream_response_time 为零
- ios - 将选择器传递给扩展
- java - getContentResolver() 不返回 mp3?
- symfony - symfony4:控制台命令中的mysql
- javascript - 如何使 v-flex 响应式
- latex - 如何在乳胶中将列表分解为页面?
- java - java流映射对象数据成员到int列表
- c# - 在新的 dev.azure.com / TFS 系统中为 UWP 设置构建