Is there a tutorial on "how to read module conventions"?

I’m struggling (as a beginner) to read the docs for some libraries. I suspect the issue is that for experienced users the type declarations are sufficient. For example, the docs for CalendarLib say that the “type of a period” is:

type +'a p constraint 'a = [< field ]

include Period.S with type +'a period = 'a p

type +'a period = 'a p
type t = Period.date_field period

There’s a lot going on here that I don’t follow! Not just the polymorphic variant stuff, but also the conventions such as the S submodule.

(For example, I spent a while thinking I should declare a type as `Days period)

Is there an introduction to this sort of thing? Technical is fine; just having it in one place would be helpful.

4 Likes

That’s a piece of code that’s more dense that what you’ll usually find.
I’ll pointers to the various constructs, but my recommendation is to read the “language extensions” chapter of the ocaml manual. I feel like every time I read it I’m learning something new.

Here are some short pointers:

  • type +'a p is called a variance annotation (p is covariant, which means that a is a subtype of b, a p is a subtype of b p)
  • after a type, you can add a constraint, which here is 'a = [< field]. It means that for whenever you encounter a a p, a is a subtype of field (others might explain better)
  • include ... with type ... is called a substitution (chapter 10.7)
  • type +'a period = 'a p is a type alias, it gives a new name to p
  • type t = ... is a type alias too, it defines t
4 Likes

Thank you, that’s very useful. I’ll look up the language extensions chapters and especially 10.7.

(Also I’m relieved to know that particular example was particularly dense!)

My understanding is

type 'a basic_color constraint 'a = [> `red | `green | `blue] 

is same as

type 'a basic_color = [ > `red | `green | `blue ] as  'a 

so if i define another type in term of basic_color type, it must at least contains `red | `green | `blue like …

type advanced_color = [ `red | `green | `blue | `pink ] basic_color 

In type +'a p constraint 'a = [< field ]
if i define another type in term of p, it must be exactly field p or (child of field) p.

Please check the code below:

type field = [ `Yes | `No ]
type +'a p constraint 'a = [< field ]

type yes_field = [ `Yes ]
type yes_p = [`Yes] p
type yes_pp = yes_field p

type no_field = [`No ]
type no_p = [`No] p
type no_pp = no_field p

type tri_field = [ field | `Maybe ]
(* OCaml will not compile below lines cause 
`Maybe or tri_field is not the subtype of field.*)
type pp = [`Maybe] p (* error *)
type ppp = tri_field p (* error *)

The above code can be seen at Sketch.sh - Interactive ReasonML/OCaml sketchbook.

pls correct me if i am wrong :grin:. I am still learning OCaml.