# Deriving show ppx and functors

**URL:** <https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346>\
**Category:** Learning\
**Created:** [February 23, 2021, 10:30am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346 "2021-02-23T10:30:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jserot](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jserot/32/2294_2.png) [@jserot](https://discuss.ocaml.org/u/jserot)\
**Post date:** [February 23, 2021, 10:30am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/1 "2021-02-23T10:30:08Z")

</div>

Hello,

I have started to use the `show` PPX extension available from [https://github.com/thierry-martinez/ppx\_show](https://github.com/thierry-martinez/ppx_show) and found it very useful.

But i’m now facing facing a problem when trying to use it in coordination with functors. I’ll try to illustrate it using a small example (which actually is a heavily trimmed down version of the code i’m working on).

Suppose i want to manipulate expressions in which constants can be of any type (not just `int`). I can do this by writing

```auto
(* file expr.mli *)
module type T = sig
  type value
  type t = Const of value | Var of string
  val zero: t
end
                         
module type VALUE = sig
  type t
  val from_int: int -> t
end

module Make (V: VALUE) : T with type value = V.t

```

```auto
(* file expr.ml *)
module type T = sig
  type value
  type t = Const of value | Var of string
  val zero: t
end

module type VALUE = sig
  type t
  val from_int: int -> t
end
                         
module Make (V: VALUE) = struct
  type value = V.t
  type t = Const of value | Var of string
  let zero = Const (V.from_int 0)
end

```

So far, so good. In particular, i can write (in file `main.ml` for ex):

```auto
module Int = struct
  type t = int
  let from_int x = x
end
           
module IntExpr = Expr.Make(Int)

let v = IntExpr.zero

```

Now, suppose i want to add a `show` function to module `Expr` to display (as strings) values of type `Expr.t`. I suppose i have to rewrite the definition of type `t` in the `Make`functor as

```auto
type t = Const of value | Var of string [@@deriving show]

```

It seems (?) i also have to add the PPX annotation in `T` _signature_ (in `expr.ml` and `expr.mli`).

Doing this, i get the following error message:

```auto
File ".../expr.ml", line 1:
Error: Unbound value pp_value

```

Seems normal: the derived `show` function for values of type `T.t` needs to know how to show values of type `Value.t`.

So, i added this line to the `VALUE` signature in files `expr.{ml,mli}`:

```auto
  val pp_value: t -> string

```

and this line to the definition of the `Int` module in `main.ml`:

```auto
  let pp_value = string_of_int

```

but i still get the error:

```auto
File ".../expr.ml", line 1:
Error: Unbound value pp_value

```

I suspect this has to do with the fact that the PPX rewritter does not have the correct function in scope in the context of functor application. I tried to inspect the ppx-expansed code (`*.pp.ml` generated by `dune`in `_build`directory) but unfortunately it is not in human readable form ☹

Any help on this subject would be appreciated

Jocelyn

---

<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:** [February 23, 2021, 10:38am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/2 "2021-02-23T10:38:34Z")

</div>

You need to make the value printer, `pp_value`, visible in scope at the definition of `t`:

```ocaml
open Value
(* or *)
let pp_value = Value.pp_value
type t = Const of value | Var of string [@@deriving show]

```

Note that you can expand the `pp.ml` file into source format by using `ocamlopt -dsource file.pp.ml`

---

<div class="post-metadata">

**Author:** ![CraigFe](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/craigfe/32/1989_2.png) [@CraigFe](https://discuss.ocaml.org/u/CraigFe)\
**Post date:** [February 23, 2021, 10:50am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/3 "2021-02-23T10:50:44Z")

</div>

Another solution might be to use the original name of `value` in the type definition, which should cause the PPX to expect the correct code:

```ocaml
module type VALUE = sig
  type t [@@deriving show]

  (* ... *)
end
                         
module Make (Value: VALUE) = struct
  type t =
    | Const of Value.t (* rather than [value] *)
    | Var of string [@@deriving show]

  (* ... *)
end

```

---

<div class="post-metadata">

**Author:** ![jserot](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jserot/32/2294_2.png) [@jserot](https://discuss.ocaml.org/u/jserot)\
**Post date:** [February 23, 2021, 11:45am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/4 "2021-02-23T11:45:00Z")

</div>

@octachron  
Thanks for your quick and useful answer.  
I should still be missing sth, howver 😕

```auto
(* expr.ml *)
...
module type VALUE = sig
  type t 
  val from_int: int -> t
end
                         
module Make (Value: VALUE) = struct
  open Value 
  type t = Const of Value.t | Var of string [@@deriving show]
  let zero = Const (Value.from_int 0)
end

```

```auto
File "examples/functor/expr.ml", line 1:
Error: Unbound value Value.pp

```

Ok, let’s `pp` to the `VALUE` signature:

```auto
module type VALUE = sig
  type t 
  val from_int: int -> t
  val pp: Format.formatter -> t -> unit
end

```

Incidentely, `pp` must have type `Format.formatter -> t -> unit` and not `t -> string` (as i expected).

Now, i guess i have to define the correct value of `pp` in the `Int` structure. Being unfamilar with formaters, i don’t know how to do this ☹

```auto
module Int = struct
  type t = int
  let from_int x = x
  let pp fmt = ???
end

```

```auto

```

---

<div class="post-metadata">

**Author:** ![jserot](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jserot/32/2294_2.png) [@jserot](https://discuss.ocaml.org/u/jserot)\
**Post date:** [February 23, 2021, 11:50am UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/5 "2021-02-23T11:50:25Z")

</div>

@CraigFe  
Thanks also for your help.  
Using the original type name in the functor definitions makes things clearer, indeed. I’ve used this reformulation in my previous answer.

I don’t understand how adding `[@@deriving show]` to the type `VALUE.t` can work without adding somewhere a reference to the actual printer. It will just define a function `VALUE.show`, won’t it ? How is this function supposed to call the “right” code ?

Sorry if this sounds confusing. I guess i have to use the tip suggested by @octachron and inspect the PPX generated code to understand what’s going on “under the hood” …

---

<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:** [February 23, 2021, 1:06pm UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/6 "2021-02-23T13:06:52Z")

</div>

You can derive the `Int` printer too:

```ocaml
module Int = struct
  type t = int [@@deriving show]
  ...
end

```

---

<div class="post-metadata">

**Author:** ![jserot](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jserot/32/2294_2.png) [@jserot](https://discuss.ocaml.org/u/jserot)\
**Post date:** [February 23, 2021, 1:23pm UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/7 "2021-02-23T13:23:02Z")

</div>

Of course !

Everything’s ok now 🙂

Here’s the final code, in case s/o encounters the same problem.

Thanks !

```auto
(* expr.mli *)
module type T = sig
  type value
  type t = Const of value | Var of string [@@deriving show]
  val zero: t
end
                         
module type VALUE = sig
  type t 
  val from_int: int -> t
  val pp: Format.formatter -> t -> unit
end

module Make (V: VALUE) : T with type value = V.t

```

```auto
(* expr.ml *)
module type T = sig
  type value
  type t = Const of value | Var of string [@@deriving show]
  val zero: t
end

module type VALUE = sig
  type t 
  val from_int: int -> t
  val pp: Format.formatter -> t -> unit
end
                         
module Make (Value: VALUE) = struct
  type value = Value.t
  type t = Const of Value.t | Var of string [@@deriving show]
  let zero = Const (Value.from_int 0)
end

```

```auto
(* main.ml *)
module Int = struct
  type t = int [@@deriving show]
  let from_int x = x
end
           
module IntExpr = Expr.Make(Int)

let v = IntExpr.zero
let _ = Printf.printf "v=%s\n" (IntExpr.show v)

```

Compiling and execution gives:

```auto
> dune build ./main.bc
> dune exec ./main.bc

v=(Expr.Make.Const 0)

```

---

<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:** [February 23, 2021, 1:36pm UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/8 "2021-02-23T13:36:03Z")

</div>

As a small refinement, you can add the deriving annotation to the type `t` in the module type `VALUE` as suggested by @CraigFe :

```ocaml
module type VALUE = sig
  type t [@@deriving show]
  val from_int: int -> t
end      

```

With this annotation, `ppx_deriving` add the corresponding generated function to the interface, which means one less possible mismatch between naming conventions.

---

<div class="post-metadata">

**Author:** ![jserot](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jserot/32/2294_2.png) [@jserot](https://discuss.ocaml.org/u/jserot)\
**Post date:** [February 23, 2021, 2:15pm UTC](https://discuss.ocaml.org/t/deriving-show-ppx-and-functors/7346/9 "2021-02-23T14:15:19Z")

</div>

Ok.  
In this case, you can (and have to, to suppress warning) remove the line

```auto
  val pp: Format.formatter -> t -> unit

```

in the definition of `VALUE` signature.

Thanks again for your helpful suggestions
