[ocaml] Interface Lcon

Hi everyone,
I have started Ocaml for 3 months, and I have one question about interface in ocaml.

Now I define a record type in the interface Lcon:
lcon.ml: type t ={a:bool;b:int}
lcon.mli: type t

If I want to create a variable of type t in an other file:
ex.ml : let lo = {Lcon.a=true;Lcon.b=3};;
--------->Is this correct?

Thank you in advance

Since in the interface, you have defined type t as an abstract type, you can’t create a value of this type using the record syntax, since the fact that it is a record is now a hidden implementation detail (that’s the whole purpose of the abstract type).

If you do not want to make it abstract, then you need to declare it in the mli file the same as you did in the ml fie:

lcon.mli: type t ={a:bool;b:int}

This will reveal the implementation and will allow users of your module to construct values directly, here are some syntaxes that are acceptable by OCaml:

{Lcon.a=true; Lcon.b=3}
{Lcon.a=true; b=3} 
Lcon.({a=true; b=3})
1 Like

Beware that the third syntax can lead to subtle bugs due to type directed disambiguation:

module type S = sig type t = {a:bool; b:int} end

module M : S = struct type t = {a:bool; b:int} end

module N : S = struct type t = {a:bool; b:int} end

(* 
  here the fields `a` and `b' in the right hand side are
  interpreted as M.a and M.b due to type directed disambiguation.
*)
M.({a=true;b=3}) = N.({a=true;b=3})
- : bool = true

(* compare to this type-checking error *)
{M.a = true; b = 3} = {N.a = true; b = 3};;
Error: The field N.a belongs to the record type N.t
       but a field was expected belonging to the record type M.t
1 Like

Thanks a lot, you saved me.

If you would rather keep the abstract type t on your interface (to hide the type structure implementation), you can provide a public API on lcon.mli:

type t
val create : bool -> int -> t

with the implementation in lcon.ml:

type t = {a: bool; b: int}
let create a b =
  {a; b}

and usage in ex.ml:

let lo = Lcon.create true 3
2 Likes