# Saving a module in a reference

**URL:** <https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330>\
**Category:** Learning\
**Created:** [September 24, 2024, 2:53pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330 "2024-09-24T14:53:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 24, 2024, 2:53pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/1 "2024-09-24T14:53:09Z")

</div>

Hi,

I am new to Ocaml and I am wondering whether there is a way to store a module in a reference?

Specifically, I would like to create a module using a functor at the beginning of my program then use it aftewards (or even in other modules). The behavior would depend on some parameter (a user entry for instance). Something like :

```auto
Module MyFunctor = Functor ….

myRef = ref MyFunctor(RightBehaviour) (*default*)

If user_input = ‘right’ then

myRef := MyFunctor(LeftBehaviour)

End;

!myRef.DoSomething

```

Any ideas?

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [September 24, 2024, 3:07pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/2 "2024-09-24T15:07:25Z")

</div>

You’re probably looking for first-class modules. Here is the corresponding section of the manual: [https://ocaml.org/manual/5.2/firstclassmodules.html](https://ocaml.org/manual/5.2/firstclassmodules.html)

Although your code example doesn’t look like OCaml code at all. If you’re using an alternate syntax, it’s possible that first-class modules are not supported.

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 24, 2024, 3:59pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/3 "2024-09-24T15:59:00Z")

</div>

We can reference a module, but the module type can’t be inferred with ref. This means you have to declare a module type:

```auto
module type DOERS = sig
  val doSomething : int -> unit
end

module A = struct
  let doSomething = print_int
end

module MyFunctor (M : DOERS) =
  struct
    let doSomething v =
      print_string "value=";
      M.doSomething v;
      print_string "\n"
  end

let myRef = ref (module A : DOERS)

let () =
  if true then
    myRef := (module MyFunctor(A));
  let module M = (val !myRef) in
    M.doSomething 42

```

Note the `(module …)` and `(val …)` syntax which converts a module into a value which can be referenced, passed as an argument to a function, etc… and vice-versa.

Beware of the case (`if` not `If`…) and `end` closes a `begin`. (Not required with an `if` and a single statement).

---

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 25, 2024, 11:51am UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/4 "2024-09-25T11:51:42Z")

</div>

Thank you for your answer.  
Now however, I have another problem.  
If I want doSomething to print integers and strings (depending on the parameter of the functor) the compiler seams to be confused on the type of the parameter of doSomething since it does know it before runtime.  
Specifically if I change your code this way :

```auto
module type DOERS = sig
  type t
  val doSomething : t -> unit
end

module A = struct
  type t=int
  let doSomething = print_int
end

module B = struct
  type t=string
  let doSomething = print_endline
end

module MyFunctor (M : DOERS) =
  struct
    type t = M.t
    let doSomething v =
      print_string "value=";
      M.doSomething v;
      print_string "\n"
  end

let myRef = ref (module A : DOERS)

let () =
  if true then
    myRef := (module MyFunctor(A));
  let module M = (val !myRef) in
    M.doSomething 42

```

I have an error :  
31 | M.doSomething 42  
^^  
Error: This expression has type int but an expression was expected of type M.t

Of course it works if I do

```auto
let module Yy = MyFunctor(A) in
      Yy.doSomething 42;

```

How can I fix that?

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 25, 2024, 12:39pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/5 "2024-09-25T12:39:25Z")

</div>

If you want your program to have a single reference (myRef) point to a module which deals with int or a string depending of a condition known at the compile time, you need a dynamic typing. But OCaml has a static typing. I guess you can’t do what you want directly.

You may use algebraic data type (`type var = Int of int | String of string …`) but since the type can’t be checked at the compile time, you have to use pattern matching and check the if you can deal with an int or a string….

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [September 25, 2024, 12:51pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/6 "2024-09-25T12:51:00Z")

</div>

In addition to @Frederic_Loyer’s answer, here are two other possible solutions:

- Adapt the definition of `myRef` (if this reference only stores modules manipulating integers):

```ocaml
let myRef = ref (module A : DOERS with type t = int)

```

- Add a function converting `int` to the type `t` to `DOERS`:

```ocaml
module type DOERS = sig
  type t
  val from_int : int -> t
  val doSomething : t -> unit
end
...
    M.doSomething (M.from_int 42)

```

---

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 25, 2024, 1:09pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/7 "2024-09-25T13:09:08Z")

</div>

Thanks both for your answer.  
I was wondering if “with type M.t=int” would help the compiler induce the correct type. But I am not sure how to use it.

Do you think it could help?

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 25, 2024, 2:54pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/8 "2024-09-25T14:54:10Z")

</div>

The code fix

```auto
let myRef = ref (module A : DOERS with type t = int)

```

is enough to solve your error.

But it will prevent you to affect to `myRef` a module where `t` is not `int`. Since I don’t know why you want the type `t` to be variable, I don’t know if it is an issue.

As I have said, OCaml has a static type system, then all types must be known at compile time. (And with the type erasure, the OCaml system prevents the definition of an introspection library or operator, well, Obj is an introspection library but very limited).

Let’s suppose you want to type:

```auto
  if condition then
    M.doSomething 42
  else
    M.doSomething "hello"

```

OCaml will infer for `M.doSomething`, two incompatible types. This can’t work whatever the M module definition.

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 25, 2024, 8:15pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/9 "2024-09-25T20:15:21Z")

</div>

What can be done is something like this:

```auto
module type DOERS = sig
   val doSomething : unit -> unit
end

let refM =
  let module A = struct
     let v = 42
     let doSomething () = print_int v
  end in
    ref (module A : DOERS)

let () = if true then
  let module B = struct
     let v = "hello"
     let doSomething () = print_string v
  end in
    refM := (module B)

let () = let module M = (val !refM) in
  M.doSomething ()

```

Here `refM` has simply the type `DOERS`… then you can affect any module (based on int, string, whatever). But you can only use fixed type functions (here `doSomething ()` the internal integer is not available from `refM`)

The proposal:

```auto
module type DOERS = sig
  type t
  val from_int : int -> t
  val doSomething : t -> unit
end
...
    M.doSomething (M.from_int 42)

```

is a bit similar: you have to use fixed type fonction and the composition of `doSomething` and `from_int` has type `int -> unit` whatever the `t` type. With this version, you can access the intermediate value, but with an opaque type: you won’t be able to do much with it, and here a `doSomethingWithInt : int -> ()` would be simpler.

But I find it hard to guess what you really want to do.

---

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 26, 2024, 8:11am UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/10 "2024-09-26T08:11:12Z")

</div>

Ok. So if I get it right, unlike other dynamically typed languages (such as Java and Smalltalk), it is not possible to write a program that adapts their behavior at runtime. That is why, for instance, it is not possible to write a universal printer (a single function that can take a string or an integer as a parameter and print it)?

Am I right?

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [September 26, 2024, 9:31am UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/11 "2024-09-26T09:31:55Z")

</div>

Types in OCaml gives a static/compile-time description of the behaviours of your program and functions. In other words, by definition types cannot change between different runtime execution. This also implies that runtime variables cannot peek at the compile-time description of their own behaviour to adjust their behaviour. This does not mean that a program cannot adapt its behaviour at runtime however.

Overall, your issue looks to me like an XY problem: putting modules into a reference is kind of doable but leans quite closely to the advanced edge of the language and is not idiomatic.

It would be probably simpler in the long run to restructure your code to avoid this pattern. For instance, you could make the generated module an explicit argument of functions and modules using it rather than using global state to pass it implicitly as an argument.

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 26, 2024, 11:27am UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/12 "2024-09-26T11:27:04Z")

</div>

Having a general printer would be useful with variable which may contains different types depending of the execution… but this can’t happen with OCaml.

If you type `let a = 42`, you know a is an integer, then you are able to type afterward `doSomethingWithInt a`.

No problem.

And `let a = if condition then 42 else "hello"` will not compile.

But you can have genericity:

```auto
let doSomething a helper =
  print_string "=";
  helper a;
  print_string "=\n";;
val doSomething : 'a -> ('a -> 'b) -> unit = <fun>

```

Here doSomething can work with any type of argument, but in order to use them efficiently, would need a compatible helper function. Functors can help making a module specialized for a type. Typically `module IntSet = Set.Make(Int)`… here the module `Int` provides the type and the helper function. But it will provide roughly the same end result: `Set` is generic, but creates `IntSet` which is specialized. You can’t have sets of anything.

---

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [September 26, 2024, 11:44am UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/13 "2024-09-26T11:44:02Z")

</div>

> [@Picasso](#):
>
> it is not possible to write a program that adapts their behavior at runtime

That depends on what you mean. It is perfectly possible to write code which has behaviour similar to that of, say, virtual functions in C++.

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 26, 2024, 12:07pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/14 "2024-09-26T12:07:56Z")

</div>

A module which implement a type module signature can be seen as a set of virtual methods. But in the main program all types are known precisely.

I had proposed an example of a module which includes its value, then the doSomething can be call with a unit argument. This can achieve some polymorphic feature.

---

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [September 26, 2024, 12:33pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/15 "2024-09-26T12:33:54Z")

</div>

Quite so. And you can do something similar with closures.

---

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 26, 2024, 1:02pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/16 "2024-09-26T13:02:45Z")

</div>

Thank you all for your answers.

Maybe if I describe a bit what I am trying to do it will be clearer.

Actually, I would like to write a program that may invoque two different tools depending on the file type passed in parameter (.t1 → tool1, .t2-\>tool2).  
The two tools have different data structures.  
So, my idea was (more or less inspired by my previous experience with OO) create a module depending on the target tool, put it in a reference then use this reference to access the desired “behavior”. Something like :

```auto

let myRef = ref (module A : DOERS)

let () =
  if (someConditionOfTheTypeOfDocument) then
    myRef := (module MyFunctor(A));
  let module M = (val !myRef) in
....

```

And later if a module needs a computation implemented in MyFunctor :

```auto
Main.M.doSomething whateverStructureIReadFromExternalTool

```

But of course here, M is not accessible from outside the () function but this is just the idea.

---

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [September 26, 2024, 1:13pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/17 "2024-09-26T13:13:30Z")

</div>

Then you have to abstract out of your two different tools a common uniformly typed module interface from which you can construct your first class modules, just as you would in designing the interface of your base class for your OO solution.

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 26, 2024, 1:23pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/18 "2024-09-26T13:23:44Z")

</div>

It seems complicated for something like this

```auto
  let () = if (isTypeA) then
     let s = readDocumentA file in
     processDocA s
  else
     let s = readDocumentB file in
     processDocB s

```

S is an OCaml structure whose the actual type depends of the document.

---

<div class="post-metadata">

**Author:** ![JohnJ](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/johnj/32/6020_2.png) [@JohnJ](https://discuss.ocaml.org/u/JohnJ)\
**Post date:** [September 26, 2024, 1:29pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/19 "2024-09-26T13:29:00Z")

</div>

I suspect that a more natural approach would be to wrap the program logic in a functor which can then operate on a module passed as a parameter. Consider:

```ocaml
module Program (M: S) = struct
  let () =
    M.doSomething whateverStructureIReadFromExternalTool
end

let () =
  if (someConditionOfTheTypeOfDocument) then
    let module M = Program (A) in ()
  else
    let module M = Program (B) in ()

```

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [September 26, 2024, 2:09pm UTC](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330/20 "2024-09-26T14:09:54Z")

</div>

If whateverStryctureReadFromExternalTool may have different OCaml type (dependent of the document type), we would have to write.

```auto
module Program (M: S) = struct
  let () =
    let str = M.readFromExternal () in
    M.doSomething str
end

let () =
  if (someConditionOfTheTypeOfDocument) then
    let module M = Program (A) in ()
  else
    let module M = Program (B) in ()

```

The type of str will typically be in the S signature and instantiated by A and B.

[Next page](https://discuss.ocaml.org/t/saving-a-module-in-a-reference/15330.md?page=2)
