Finding OCaml Core Library Interface Files
[md]
When you install Core via opam, the interface files (.mli) are stored in your OPAM switch directory. The exact path depends on your OCaml version and OPAM setup.
## Standard Location
The .mli files for Core are located at:
~/.opam/$(ocaml -version | awk '{print $NF}')/lib/core/
where the OCaml version is part of the switch path. For example, with OCaml 5.2:
ls ~/.opam/5.2/lib/core/*.mli | head -10
If you use a named switch instead of the default:
opam switch list
# Then look in ~/.opam/<switch-name>/lib/core/
## Finding the Path Programmatically
Use ocamlfind to locate the Core library directory:
ocamlfind list | grep core
ocamlfind printconf stdlib
Or get the exact path with:
ocamlfind query core
This outputs the directory containing both .cmi (compiled interface) and .mli (source interface) files.
## Common Interface Files
Core provides interface files for all its modules. Some frequently referenced ones:
– core.mli — The main Core module with all re-exports
– list.mli — Extended list operations
– option.mli — Option type utilities
– string.mli — Enhanced string functions
– int.mli — Integer operations
– map.mli and set.mli — Map and Set data structures
– result.mli — Result type helpers
– printf.mli — Type-safe formatting
## Reading .mli Files in Your Editor
**With Merlin/ocaml-lsp:**
If you use Merlin or ocaml-lsp (for VS Code’s OCaml Platform extension), M-x merlin-type-enclosing or “Go to Definition” automatically opens the correct .mli file.
**Manual lookup:**
less $(ocamlfind query core)/list.mli
**In utop:**
#use "core.top";;
#show List.map;; (* Shows the type signature *)
## Core vs Core_kernel
Core has been split into multiple packages:
– **core_kernel** — Portable subset that works on all platforms (including JavaScript via js_of_ocaml)
– **core** — Full Core, including Unix-specific functionality
– **core_unix** — Unix-specific extensions (in newer versions)
The .mli files for each are in separate directories:
ocamlfind query core_kernel
ocamlfind query core_unix
For most non-Unix-specific modules (List, Option, String, Map, etc.), the interface files are in core_kernel.
## Troubleshooting Missing .mli Files
**”Unbound module Core”:**
Make sure Core is installed in your current switch:
opam list | grep core
opam install core
**Can’t find .mli after install:**
Rebuild the package documentation:
opam reinstall core
**Wrong switch:**
Verify you’re using the right OPAM switch:
opam switch show
eval $(opam env)
## Alternative: Use odoc for Browsable Docs
If you want HTML documentation instead of raw .mli files:
opam install odoc
opam doc core
This generates browsable HTML documentation from the .mli files with proper cross-references and search.
## Generating Documentation for Your Project
If you’re building a library that uses Core, generate docs for your own .mli files:
# Install odoc
opam install odoc
# Build docs for your project
cd your-project
eval $(opam env)
odoc compile your_module.mli
# Or use dune to build all docs
dune build @doc
The generated HTML appears in _build/default/_doc/_html/.
## Working with .mli Files in Practice
When developing OCaml libraries, writing .mli files is considered best practice. Here’s a typical workflow:
**1. Write the interface first (.mli):**
(* mylib.mli *)
val process : string -> string option
type config = { verbose: bool; max_size: int }
val make_config : verbose:bool -> max_size:int -> config
**2. Implement it (.ml):**
(* mylib.ml *)
let process input =
if String.length input = 0 then None
else Some (String.trim input)
type config = { verbose: bool; max_size: int }
let make_config ~verbose ~max_size = { verbose; max_size }
**3. The .mli acts as the public API contract.**
Any value not listed in the .mli is private to the module.
This pattern — interface-driven development — is central to OCaml’s module system and helps catch errors early.
