GHCi :browse命令如何查看导入模块?无源码时如何获取模块信息?
Great question—this is a common pain point when building code generation tools in Haskell, especially when you don’t have access to the target module’s source code. Let’s break down your options, explain how GHCi does its magic, and cover tools you might have missed.
How GHCi Works Without Source Code
GHCi doesn’t need source files because it leverages the GHC API under the hood to interact with compiled module artifacts: specifically, the .hi (interface) and .o (object) files. These files store all the metadata GHC needs to understand a module’s types, functions, data constructors, and exports—everything you’d require for code generation. When you load a module in GHCi, it’s essentially using the API to parse these interface files and build an in-memory representation of the module’s structure.
Your Best Options for Code Generation Without Source
1. Use the GHC API Directly
This is the most powerful approach, since it’s exactly what GHCi relies on. The ghc package (part of GHC’s official tooling) lets you programmatically load modules, query their interface information, and inspect all their symbols. Here’s a rough outline of how to use it:
- Initialize a GHC session with
GHC.defaultErrorHandlerandGHC.runGhc. - Configure package databases and import paths so GHC can locate the target module.
- Load the module with
GHC.loadModuleand retrieve its metadata usingGHC.getModuleInfo. - From the
ModuleInfovalue, you can access exports, data types, type signatures, and more via functions likeGHC.modInfoExportsor by resolving names withGHC.lookupName.
This gives you full, low-level control over module inspection—just like GHCi.
2. Extend Template Haskell Beyond reifyModule
You’re right that reifyModule only provides dependency information, but Template Haskell (TH) has more to offer. The reify function can inspect individual names (types, functions, constructors) as long as you can reference them in your TH code. For example:
- To get details about the
Mapdata type fromData.Map, runreify ''Map—this returns anInfovalue containing the type’s constructors, kind, and other metadata. - To inspect a function like
Map.lookup, usereify 'Map.lookupto retrieve its type signature and related details.
The caveat is that TH runs at compile time, so the target module must already be compiled (i.e., present in your build dependencies with a .hi file available). But for many code generation use cases, this is perfectly feasible.
3. Parse .hi Files Directly
If you want to avoid the overhead of the full GHC API, the hi-file-parser library lets you parse .hi files directly into structured Haskell data types. You can extract exports, type definitions, and other metadata without spinning up a full GHC session—making it a lightweight alternative for basic interface inspection.
Key Takeaways
- GHCi’s core capability comes from the GHC API—use it if you need deep, full-featured access to module metadata.
- Template Haskell’s
reify(not justreifyModule) is useful for compile-time code generation when you can reference target symbols. - For lightweight offline parsing,
hi-file-parseris a great choice for reading.hifiles directly.
内容的提问来源于stack exchange,提问作者Magicloud

