在SML/NJ构建配置中引用外部SML文件的问题
解决SML/NJ中Functor引用无导出模块外部文件的问题
问题背景
现有一套可正常运行的SML/NJ构建配置,尝试在functor中通过use "external.file";引用外部文件时失败。需在不修改该外部文件(无任何模块导出)的前提下,在functor中调用其中的函数进行测试。将该文件添加到build.cm的is列表后,系统报错提示无模块导出,需调整配置实现需求。
解决方案
利用SML/NJ的CM(Compilation Manager)local块特性,将外部文件标记为本地依赖,使其内容对后续源码可见且无需导出模块。具体操作如下:
1. 调整build.cm配置
在is块中用local包裹外部文件,告知CM该文件为本地依赖,不要求其导出任何模块:
source (-) (* export all defined modules *) structure Test signature THEOREM functor Theorem is (* Import standard libraries *) $/basis.cm $/smlnj-lib.cm (* 本地包含外部文件,无需导出模块 *) local ./external.sml end (* 原有源码文件 *) ./test.sml ./theorem.sig ./theorem.fun
2. 修改Functor文件(theorem.fun)
移除原文件中复制的update'函数定义,直接调用外部文件中的函数即可:
functor Theorem() : THEOREM= struct val update = update' [] [(1, "one")] (1,"one") end
3. 外部文件保持不变
假设外部文件external.sml内容为:
fun update' front [] (l,n) = NONE | update' front ((l',n')::pairs) (l,n) = if l=l' then SOME(front @ ((l,n)::pairs) ) else update' ((l',n')::front) pairs (l,n)
原理说明
- CM的
local块用于声明仅当前构建配置依赖的本地文件,这些文件的顶层定义会被后续编译的源码直接可见,无需导出模块。 - 无需使用
use指令,CM会自动处理文件的编译顺序和依赖关系,避免了use带来的路径与编译顺序问题。
内容的提问来源于stack exchange,提问作者Mohan Radhakrishnan
相关产品推荐
相关产品推荐

