Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge OCaml module types (signatures) defining the same type?

Tags:

ocaml

In OCaml, I have two module types defining a type t:

module type Asig = sig
    type t
    val a : t
end

module type Bsig = sig
    type t
    val b : t
end

I want to automate the creation of a module type merging them. I want to create a module type equivalent to:

module type ABsig_manual = sig
    type t
    val a : t
    val b : t
end

I tried

module type ABsig = sig
    include Asig
    include Bsig
end

but this fails with Error: Multiple definition of the type name t. It seems impossible to add a type constraint to the include so I'm stuck.

Context: I have a module AB that does implement both signatures and I want to feed it to a functor like:

module MakeC(AB) = struct
    type t = AB.t list
    let c = [AB.a; AB.b]
end

module C = MakeC(AB)

I could use two arguments like in:

module UglyMakeC(A : Asig)(B : Bsig with type t = A.t) = struct
    type t = A.t list
    let c = [A.a; B.b]
end

module C = UglyMakeC(AB)(AB)

but this (is ugly and) doesn't scale well to more functors or more signatures to merge.

So, how can I automate merging those two module types? I can modify A and B as needed but I want to keep them separated. Also, maybe my approach is completely wrong, and in that case I'd love pointers to a better direction.

Type sharing in OCaml - typechecker error is related but merges modules, not module types.

like image 914
jacquev6 Avatar asked Oct 02 '15 16:10

jacquev6


1 Answers

Here is the way to do it :

module type Asig = sig
    type t
    val a : t
end

module type Bsig = sig
    type t
    val b : t
end

module type ABsig = sig
    include Asig
    include Bsig with type t := t
end

It's called "destructive substitution".

like image 187
Drup Avatar answered Sep 18 '22 17:09

Drup