Ocaml combining signatures
Suppose I have two signatures, Ordered, and Field
module type ORDERED = sig
type t
type comparison = LT | EQ | GT
val cmp : t -> t -> comparison
end
module type FIELD = sig
type t
val (+) : t -> t -> t
val ( * ) : t -> t -> t
val inv : t -> t
val neg : t -> t
val zero : t
val one : t
end
And I want to make a functor that takes two Ordered Fields
and produces another Ordered Field
(say operations are applied component-wise and we use dictionary order for comparison). How would I specify that the "input modules" satisfy two signatures simultaneously?
Here is some strawman syntax for what I want to do:
module NaivePair = functor (Left : ORDERED & FIELD) (Right : ORDERED & FIELD) ->
struct
type t = Left.t * Right.t
(* definitions *)
end
It might be the case that there's an elegant way to take a "union" of signatures (but not an anonymous union), or create a wrapper module around concrete ORDERED
and FIELD
implementations that just happen to share a type t. I am curious what the idiomatic OCaml way to do what I am trying to achieve is.
Define a new module type using include
and with type t := t
:
module type ORDERED_FIELD = sig
include ORDERED
include FIELD with type t := t
end
Without with type t := t
, the definition is rejected since both ORDERED
and FIELD
declares the type of the same name. include FIELD with type t := t
is to "substitute" t
of FIELD
by ORDERED.t
.
ocamlc -i -c x.ml
to see what ORDERED_FIELD
is exactly what you want:
$ ocamlc -i -c x.ml
...
...
module type ORDERED_FILED =
sig
type t
type comparison = LT | EQ | GT
val cmp : t -> t -> comparison
val ( + ) : t -> t -> t
val ( * ) : t -> t -> t
val inv : t -> t
val neg : t -> t
val zero : t
val one : t
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With