我来这里是为了别的东西,但试图写下我的问题,我意识到我没有办法做到这一点。我已经使用 mirage 和 irmin 一段时间了,只要所有代码都保留在 Main 模块中,一切都很棒。但是,当然,它很快就会变成一个大得离谱的文件,并且试图将它拆分成模块让我对类型逃逸其作用域之类的东西感到抓狂。
不是仅仅将控制台从 start 传递给其他一些函数,我必须将那些其他函数放在一个函子中,该函子将接受Mirage_types_lwt.CONSOLE实际的控制台变量,这意味着一切最终都在从头开始实例化的函子中,并以一个无法阅读的混乱代码。
我在制作一个巨大的丑陋模块来轻松存储和传递所有这些时遇到了问题(从常规代码中“隔离”需要这些混乱的部分),而且我无法弄清楚如何声明这样的东西:
module type ContextConfig = sig
module Store
val clientctx : Client.ctx
....
end
let mkContextConfig (module Store : Repo) ctx =
(module struct
(module Store : Repo)
let clientctx = ctx
end : ContextConfig)
Run Code Online (Sandbox Code Playgroud)
(Repo 是我用来包装 Irmin 函子的模块)。这显然不起作用,我尝试了很多语法,我猜这是不可能的,这意味着我做错了什么?
我希望得到有关以干净的方式处理所有这些函子和类型的正确方法的建议,我如何传递诸如控制台或管道之类的东西,而不必对 Main 模块中的所有内容进行函子化和实例化来传递它约后?
类似的定义是可能的:
module type REPO = sig end
module type CONTEXT_CONFIG = sig
module Store : REPO
val client_ctx : int
end
let mkContextConfig (module Store : REPO) ctx =
(module struct
module Store = Store
let client_ctx = ctx
end : CONTEXT_CONFIG)
Run Code Online (Sandbox Code Playgroud)
(进行一些无趣的更改以进行代码类型检查。)