# Module types, functors and types

**URL:** https://discuss.ocaml.org/t/module-types-functors-and-types/11199
**Category:** Learning
**Tags:** functor
**Created:** [January 16, 2023, 8:03pm UTC](https://discuss.ocaml.org/t/module-types-functors-and-types/11199 "2023-01-16T20:03:56Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![jnavila](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jnavila/32/527_2.png) [@jnavila](https://discuss.ocaml.org/u/jnavila)
#### Post date: [January 16, 2023, 8:03pm UTC](https://discuss.ocaml.org/t/module-types-functors-and-types/11199/1 "2023-01-16T20:03:56Z")

</div>

Hi everyone,

While developing my small app, I’m facing an issue that is sticking me.

The application draws KiCad electronic schematics, and for this, a module `Painter` abstracts a canevas and the functions to draw on it:

```ocaml
module type Painter = sig
  (** A module able to paint a canvas with several graphic primitives
      and then to process the canvas into a picture file format. The
      functions are supposed to be pure *)

  (** the canvas of the painter *)
  type t

  val get_context : unit -> t
  (** [get_context ()]
      @return a new painting canvas *)

  ... primitives functions
end

```

This module was manipulated by the interpreter of a given version V5 of the schematic file. (No so) Recently, a new file format V6 for schematics was introduced. So I introduced a schematic painter type to abstract the schematic format:

```ocaml
module type SchPainter = sig
  (** A module able to paint a schematic file in a painter context *)

  (** the schematic context *)
  type schContext

  (** the underlying context *)
  type painterContext

  val initial_context : ?allow_missing_component:bool -> revision -> schContext
  (** [initial_context allow_missing_component revision]
      @return an new empty context *)

  val parse_sheet : schContext -> String.t -> schContext
  (** [parse_line content context] parse a [content] of schematic and
      update [context].
      @return the updated context *)

  val output_context : schContext -> painterContext
  (** [output_context context output] write the [context] as a image
      format to [output] *)
end

```

Which are created via functors whose type is:

```ocaml
module type KicadSchHandler = sig

  module MakeSchPainter: functor (P: Painter) -> SchPainter

end

```

Then I can create the two formats:

```ocaml
module MakeSchPainter (P : Painter) :
  SchPainter with type painterContext = P.t = struct 
  
  type painterContext = P.t

  ... Implementation
end

```

So far, so good. But at some point, I create a SchPainter from a SvgPainter , and I want to get back the SVG content of the canevas as a string :

```ocaml
  let schHandler =
    if String.ends_with ~suffix:".sch" sch then
      (module Kicadsch.V5: Kicadsch.Sigs.KicadSchHandler)
    else if String.ends_with ~suffix:".kicad_sch" sch then
      (module Kicadsch.V6: Kicadsch.Sigs.KicadSchHandler)
    else
      failwith ("unknown file extenstion for " ^ sch) in
  let module SchPainter = (val schHandler) in
  let module SvgSchModule = SchPainter.MakeSchPainter(SvgPainter) in
  let open SvgSchModule in
  let initctx = initial_context No_Rev in
  let fileout = build_outputfilename outdir sch in
  let%lwt o = Lwt_io.open_file ~mode:Lwt_io.Output fileout in
  let%lwt i = Lwt_io.open_file ~mode:Lwt_io.Input sch in
  let%lwt contents = Lwt_io.read i in
  let endcontext = parse_sheet initctx contents in
  let canvas = output_context endcontext in
  let%lwt () = Lwt_io.write o (SvgPainter.write canvas) in
  let%lwt () = Lwt_io.close i in
  Lwt_io.close o

```

But the type checker chokes the line `SvgPainter.write canvas`

I understand that the functor eliminates the original `painterContext` type in the generated SchPainter, but I don’t really see how to get it back for my own manipulation.

---

<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: [January 16, 2023, 8:32pm UTC](https://discuss.ocaml.org/t/module-types-functors-and-types/11199/2 "2023-01-16T20:32:38Z")

</div>

> [@jnavila](#):
>
> I understand that the functor eliminates the original `painterContext` type in the generated SchPainter, but I don’t really see how to get it back for my own manipulation.

Have you tried reexporting the type equality between `painterContext` and `P.t`?

```auto
module MakeSchPainter(P : Painter) : SchPainter with type painterContext = P.t

```

Cheers,  
Nicolas

---

<div class="post-metadata">

### Author: ![jnavila](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jnavila/32/527_2.png) [@jnavila](https://discuss.ocaml.org/u/jnavila)
#### Post date: [January 17, 2023, 9:35pm UTC](https://discuss.ocaml.org/t/module-types-functors-and-types/11199/3 "2023-01-17T21:35:11Z")

</div>

Thank your for your reply! It gave me a good hint and I added this type equality in the mli files of V5 and V6.

It worked!
