# Functor with an unknown type in its first-class module

**URL:** <https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654>\
**Category:** Learning\
**Tags:** functor\
**Created:** [April 8, 2022, 4:57pm UTC](https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654 "2022-04-08T16:57:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![eWert-Online](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ewert-online/32/4130_2.png) [@eWert-Online](https://discuss.ocaml.org/u/eWert-Online)\
**Post date:** [April 8, 2022, 4:57pm UTC](https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654/1 "2022-04-08T16:57:40Z")

</div>

Hello 👋

I want to make a functor, which only needs a single function implementation as its argument.  
My problem is, that I don’t want to have to provide the input type of the function in the first-class module (as its type is quite complex and always the same).  
Sorry, if the terminology I am using is incorrect 😬  
I hope you can understand me anyways.

Is there a way the following simplified example can work?  
Basically the `'a` should be replaced by the type `t` which is declared inside `Make`.

```auto
module type S = sig
  val to_string : 'a -> string
end

module Make (Impl : S) = struct
  type t = int

  let to_string : t -> string = Impl.to_string
end

module MyModule = Make (struct
  let to_string = string_of_int
end)

```

Thank you for your help!

- Torben

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [April 8, 2022, 5:39pm UTC](https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654/2 "2022-04-08T17:39:24Z")

</div>

Perhaps you can just define the type outside the functor argument ?

```auto
type large_type = ...

module MyModule1 = Make (struct type t = large_type let to_string = ... end)
module MyModule2 = Make (struct type t = large_type let to_string = ... end)
(* etc *)

```

Cheers,  
Nicolas

---

<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:** [April 8, 2022, 7:00pm UTC](https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654/3 "2022-04-08T19:00:01Z")

</div>

Writing the type is probably the simplest solution.

However, it is possible to use first-class modules to lift an inferred type to the module level:

```ocaml
module type S = sig
  type t
  val to_string: t -> string
end

let make (type a) f : (module S with type t =a) =
  (module struct
    type t = a
    let to_string = f
  end)

module R = (val (make Fun.id))

```

I use this pattern from time to time when I encode some computation in types with GADTs and want to extract the result of the computation at the module level.

---

<div class="post-metadata">

**Author:** ![ghulette](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ghulette/32/2067_2.png) [@ghulette](https://discuss.ocaml.org/u/ghulette)\
**Post date:** [April 8, 2022, 9:36pm UTC](https://discuss.ocaml.org/t/functor-with-an-unknown-type-in-its-first-class-module/9654/4 "2022-04-08T21:36:23Z")

</div>

For more info on this technique see the similar example in Real World OCaml: [First-Class Modules - Real World OCaml](https://dev.realworldocaml.org/first-class-modules.html) (in the subsection **More on Locally Abstract Types** ).
