Ocaml 路过;这";模块的实例

Ocaml 路过;这";模块的实例,ocaml,Ocaml,使用幻影,我有一个相当大的函子混乱。为了稍微整理一下,我制作了一个丑陋的Context模块,对代码中需要传递的所有类型和值进行参数化。因为显然只传递我需要的值将允许类型“逃出它们的作用域”引用编译器,所以我最终将该模块作为参数传递给函数 funx(模块Ctx:Context)= 使用起来有点烦人,但它可以工作。 所以基本上: let module Context = MkContext(S)(C)(ContextConfig) in S.listen_tcpv4 stackv4 ~port:84

使用幻影,我有一个相当大的函子混乱。为了稍微整理一下,我制作了一个丑陋的
Context
模块,对代码中需要传递的所有类型和值进行参数化。因为显然只传递我需要的值将允许类型“逃出它们的作用域”引用编译器,所以我最终将该模块作为参数传递给函数
funx(模块Ctx:Context)=

使用起来有点烦人,但它可以工作。 所以基本上:

let module Context = MkContext(S)(C)(ContextConfig) in
S.listen_tcpv4 stackv4 ~port:8442 (Context.handleConnection console);
从Context.handleConnection内部,我需要调用一个函数,该函数将上下文作为参数。我想其中一种方法是将上下文传递给handleConnection,如下所示:

S.listen_tcpv4 stackv4 ~port:8442 (Context.handleConnection console (module Context));
然后把它从handleConnection作为一个this传递给需要的函数,但我想一定有更好的方法


编辑:甚至不能这样做,我需要将模块类型设置为递归的,这看起来并不简单。

我不确定这是否是一个好主意,但可以通过递归模块定义递归模块类型:

module rec R: sig 
  module type S = sig
    val f: (module R.S) -> int -> int
  end
 end = R
我们在这里使用的技巧是在递归模块扩展期间添加类型级组件,以避免重复。如果没有这个技巧,最好开始用占位符
self
type来定义内部模块类型

   module type I = sig
     type self
     val f: self -> int -> int
   end
然后,我们可以在递归定义期间删除占位符类型:

  module rec R : sig
    module type S = I with type self := (module R.S)
  end = struct
    module type S = I with type self := (module R.S)
  end
最后,我们可以使用递归模块类型

module X = struct
    let f (module Self: R.S) n =
      if n = 0 then 1 else n * Self.f (module Self) (n-1)
end
let six = X.f (module X) 3
你能创造一个例子来说明这个问题吗?这将使问题和随后的答案更加清晰,并使我们这些非大师更容易胡闹和偶然发现一些有用的东西。