Search code examples
moduleocamlstructureencapsulationsignature

What is the reason to declare private type in a struct?


OCaml allows to mark type as private in the signature. And it makes sense. The object of type declared as private can be created only inside the module and be read outside.

module X : sig
  type t = private { value : int }
  val make : int -> t 
end = struct
  type t = { value : int }
  let make x = { value = x }
end

let x = X.make 3        (* OK *)
let value = x.value     (* OK *)
let x = X.{ value = 3 } (* ERROR *)

It is clear. But OCaml also provides the ability to declare private type inside the module structure.

module X : sig
  type t = private { value : int }
  val make : int -> t 
end = struct
  type t = private { value : int }
  let make x = { value = x } (* ERROR *)
end

Error: Cannot create values of the private type t

It looks like a stupid feature because nobody needs a type when it is impossible to create any object of it.

For me looks more logical when private is an attribute that is allowed only in the signature level like abstract type.

What does OCaml have a private type in the struct for?


Solution

  • For the same reason that you can declare fully abstract types: values of those types can be created by external functions, for instance

    type t = private int
    external f: unit -> t = "some_c_function"
    

    Moreover, this makes type definitions more regular since the same type definition is always allowed in both signatures and structures.