You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Located HsModule中收集所有EpAnn及其entry与comments对?

从Located HsModule中收集EpAnn的entry与comments对

问题背景

使用GHC 9.2.2,需要从Located HsModule中提取所有EpAnn类型的值,仅保留其entry与comments组成的对,不关心EpAnn的类型参数。最初针对EpAnn AnnListItem的收集代码可正常运行,但将收集逻辑改为泛型的EpAnn a后编译失败,尝试自定义EpAnnWrapper包装器也无法解决问题,当前使用SYB库,也可使用其他库实现需求。

可行解决方案

基于SYB库的实现

SYB的listify要求目标类型固定,无法直接匹配多态的EpAnn a,但可以利用Typeable的动态类型检查,结合everything遍历所有节点并收集目标数据:

  1. 定义结果类型:
type EpAnnPair = (AnnEntry, [AnnComment])
  1. 实现收集函数:
import Data.Generics
import GHC.Hs
import GHC.Types.SrcLoc

collectEpAnnPairs :: Data a => a -> [EpAnnPair]
collectEpAnnPairs = everything (++) collectSingleEpAnn
  where
    collectSingleEpAnn :: Data b => b -> [EpAnnPair]
    collectSingleEpAnn node = case cast node of
      -- 匹配任意EpAnn实例,提取entry和comments字段
      Just (EpAnn entry comments _) -> [(entry, comments)]
      Nothing -> []
  1. 调用示例(假设已解析得到Located HsModule实例):
main :: IO ()
main = do
  let locatedModule :: Located HsModule = -- 你的解析结果
      annPairs = collectEpAnnPairs locatedModule
  mapM_ print annPairs

原理说明

  • everything (++)会递归遍历数据结构的所有节点,将每个节点的收集结果合并为一个列表。
  • cast函数会动态检查当前节点是否为任意EpAnn a类型实例,成功则提取所需的entry和comments字段,失败则返回空列表,不影响结果。

依赖配置

确保haskell-playground.cabal中包含必要依赖:

build-depends:
  base >= 4.16.0.0,
  syb,
  ghc >= 9.2.2 -- 或使用ghc-lib-parser替代ghc包

内容的提问来源于stack exchange,提问作者toku-sa-n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 07:24:22