I have a module signatures like this:

```
module type Base_X = sig
type t
end
module type Base_Y = sig
type t
end
module type A_sig = sig
module Some_X : Base_X
module Some_Y : Base_Y
module Z : sig
val f : Some_X.t -> Some_Y.t
end
end
```

and two types `x`

and `y`

.

Modules that implement `A_sig`

will define `Some_X`

and `Some_Y`

as extending `Base_X`

and `Base_Y`

in a way that allows instances of `x`

and `y`

to be converted to `Some_X.t`

and from `Some_Y.t`

. For instance, one implementation of `Some_X`

might have type

```
module type X1_sig = sig
type t
val x_to_string : x -> string
val string_to_t : string -> t
end
```

For each possible module type like `X1_sig`

there will be a functor `X1_func`

(or function using first-class modules) that takes `Some_X1 : X1_sig`

to (a module containing) a function `x -> Some_X1.t`

, and likewise there will be functors to create functions `Some_Y.t -> y`

.

I would like to define a functor `Make`

that takes a module `A : A_sig`

and appropriate functors `X_func`

and `Y_func`

, and produces a function `f : x -> y`

by chaining `X_func`

, `A.Z.f`

and `Y_func`

. It seems like this isn’t possible to do completely generally, and multiple `Make`

functors are needed for different values of `X_func`

and `Y_func`

. But is there a way to do it more generally than by defining specific versions of `Make`

for each possible pair of `X_sig/X_func`

and `Y_sig/Y_func`

? I would be happy with an approach that handles each `X_sig`

and `Y_sig`

separately, but I can’t work out how to do that (defining a functor/function with type `x -> Some_X1.t`

causes the type constructor `Some_X1.t`

to escape its scope).