OCaml如何从其他模块访问deriving注解生成的函数
无法访问的原因
ppx_deriving 系列插件生成的所有衍生函数,默认和对应的类型定义在同一个模块作用域内。你在 ./lib/books.ml 中为 book 类型添加 [@@deriving yaml] 注解后,生成的 book_to_yaml、book_of_yaml 等函数,都是 Books 模块的成员,不会自动暴露到全局作用域。
你在 ./bin/main.ml 中直接调用book_to_yaml时,编译器只会在当前 Main 模块的作用域内检索对应函数,自然会提示函数不存在。
正确调用方案
方案1:带模块前缀直接调用
最简单的处理方式,调用函数和使用类型时都加上所属模块的前缀:
(* ./bin/main.ml *) let () = let (b: Books.book) = { title = "Cryptonomicon"; authors = [ "Neal Stephenson" ] } in Yaml.pp Stdlib.Format.std_formatter (Books.book_to_yaml b);
方案2:局部打开模块简化重复调用
如果需要多次调用Books模块下的类型和衍生函数,可以用局部打开减少重复代码:
(* ./bin/main.ml *) let () = let open Books in let b = { title = "Cryptonomicon"; authors = [ "Neal Stephenson" ] } in Yaml.pp Stdlib.Format.std_formatter (book_to_yaml b);
方案3:配置模块接口导出函数(针对有mli文件的场景)
如果你的Books模块有对应的.mli接口文件,必须在接口文件的同类型定义上也添加[@@deriving yaml]注解,否则生成的转换函数会被视为模块私有内容,哪怕加了模块前缀外部也无法访问:
(* ./lib/books.mli *) type book = { title: string; authors: string list } [@@deriving yaml]
没有单独写.mli接口文件的情况下,模块内所有定义默认公开,不需要额外配置,直接按方案1、2调用即可。
小提示:所有
ppx_deriving_*系列插件的衍生函数访问逻辑都和上述规则一致,不限于yaml衍生注解。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

