Remix.run Logo
debugnik 5 days ago

In short, OCaml modules are used for coarse-grained generics.

Modules are like structurally-typed records that can contain both abstract types and values/functions dependent on those types; every implementation file is itself a module. When passed to functors (module-level functions), they allow you to parameterize large pieces of code, depending on multiple types and functions, all at once quite cleanly. And simply including them or narrowing their signatures is how one exports library APIs.

(The closest equivalent I can imagine to module signatures is Scala traits with abstract type members, but structurally-typed and every package is an instance.)

However, they are a bit too verbose for finer-grained generics. For example, a map with string keys needs `module String_map = Map.Make(String)`. There is limited support for passing modules as first-class values with less ceremony, hopefully with more on the way.