Pass modules to other modules

209 Views Asked by At

I'm trying to use Irmin with MirageOS, and I'm struggling with all those modules. I took a look at the Canopy sources to try and figure out how Irmin is supposed to be used, and I have this :

let start console clock resolver conduit =
  let (module Context) = Irmin_mirage.context (resolver, conduit) in
  let module Mirage_git_memory = Irmin_mirage.Git.Mem.KV(Context)(Git.Inflate.M) in
  let module Store = Mirage_git_memory(Irmin.Contents.String) in
  [...]

From the start function I can use Store fine, set and read the repo .. How do I pass Store around ? Since all of these types depend on start's parameters, I can't (or don't know how) to define those modules anywhere else, and all my attempts to pass or define Store anywhere else have failed with errors about constructor that would escape their scopes. I did manage to create a store.ml file of my own (like in Canopy), but it's just moving the problem to a new module, I still have no idea how to pass it around.

In canopy they seem to use the Store module exclusively from the start function, which for their purpose is fine, but isn't for what I want to do.

I'm trying to use Irmin, but I assume it's not an Irmin problem, I'm probably just very wrong as to how the module system works in ocaml. When I try to pass it to another function or module I end up with errors like

The signature for this packaged module couldn't be inferred.

Which seems logical, but I don't know how to fix that.

Thanks

1

There are 1 best solutions below

3
On

First class modules (like let (module Context)) are a bit difficult to handle for the OCaml compiler, and in particular it is often not able to infer their type by itself.

The solution is to add a manual annotation:

let (module Context : Irmin_mirage.CONTEXT) = Irmin_mirage.context (resolver, conduit) in
...