Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include a signature in an extended module?

Tags:

ocaml

Let's say we wanted to extend an existing module like List.

We would generally just include the module we want to extend, and then add the new methods to its structure:

# module List = struct
    include List
    let addOne x = x + 1
  end;;

which gives us the signature:

module List :
  sig
    val length : 'a list -> int
    val compare_lengths : 'a list -> 'b list -> int
    val compare_length_with : 'a list -> int -> int
    :
    val addOne : int -> int
  end

Now if I wanted to explicitly extend the module's signature as well, I'd try to do something like:

# module List : sig
    val addOne : int -> int
  end = struct
    include List
    let addOne x = x + 1
  end;;

but now we see that our signature becomes:

module List :
  sig
    val addOne : int -> int
  end

By defining our own signature like this, we're excluding the List's signature so our module's structure now doesn't include any of the original List methods.

Now, if this wasn't List but a module that I've personally created, then we could just define the signature separately and include it in the signature of the module we're extending.

# module List : sig
    include MY_LIST
    val addOne : int -> int
  end = struct
    include MyList
    let addOne x = x + 1
  end;;

But when we have something like List, or some other 3rd party module we're consuming, is there a way to extend it and include our own signature?

Is it possible to do this, and if not, is there a workaround that's commonly used to achieve similar behavior / is there a canonical way to handle these types of situations?

like image 526
Nick Zuber Avatar asked Jan 03 '23 03:01

Nick Zuber


1 Answers

There is module type of for those situations:

module List: sig
  include module type of List
  val more: unit
end = struct
  include List
  let more = ()
end
like image 69
octachron Avatar answered Jan 04 '23 17:01

octachron