- Use functors to parameterize modules over their dependencies: `module Make (Db : DB_INTF) = struct ... end` enables dependency injection without runtime overhead.
- Define module signatures (`module type S = sig ... end`) before writing implementations — signatures serve as contracts and documentation.
- Use `include` to extend or compose module types: `module type EXTENDED = sig include BASE; val extra : unit end`.
- Use first-class modules `(module M : S)` to pass module implementations as values when runtime selection is needed.