Un des cas d'usage des modules est de pouvoir définir une implémentation minimaliste d'une interface, puis de l'appliquer à un foncteur pour dériver automatiquement de nombreuses fonctions.
Continuons sur l'exemple des files de priorités. On pourrait à partir de cette file de priorité définir automatiquement des fonctions pour créer une file de priorité depuis une liste, ou extraire une liste triée depuis une file de priorité. Cela correspondrait à enrichir l'interface des modules de priorité pour obtenir ceci :
On note ici l'utilisation du mot-clé include qui permet d'inclure dans une interface le contenu d'une autre interface. En plus des définitions de la file de priorité minimale, nous trouvons donc les fonctions de conversions de/vers les listes et une fonction de tri.
Il n'est alors pas nécessaire de redéfinir entièrement le module de files de priorité : on peut réutiliser l'implémentation des tas gauches, à l'aide d'un foncteur.
À nouveau, dans l'implémentation, include permet de récupérer toutes les définitions d'un module. On peut noter qu'il faut correctement exporter les deux types t et key. Dans ce foncteur, l'argument Heap peut être n'importe quel module implémentant l'interface MinimalHeap, ce qui a deux conséquences :
Un exemple d'utilisation de cette technique est la librairie Ocamlgraph d'algorithmes sur les graphes. Tous les algorithmes sont écrits dans des foncteurs, prenant un module d'interface Graph (en fait, il y a même plusieurs interfaces possibles pour les graphes). Chaque algorithme est donc implémenté une fois, définitivement, et peut être ensuite utilisé avec n'importe quelle implémentation de graphes, ce qui permet d'utiliser des représentations très haut-niveau de graphes, selon les besoins de l'utilisateur de la librairie. Des implémentations par défaut sont aussi proposées.
Étudions un autre exemple. Rappelons l'interface des monades :
L'un des intérêts des monades est de modéliser le séquencement d'actions : faire une chose, puis une autre, puis une autre. Nous avons vu à travers de nombreux exemples que le (>>=) s'utilise de la même façon que le pipe (|>), mais avec des fonctions produisant des résultats dans le type paramétré de la monade.
Une fois les deux opérations return et (>>=) définies, il est possible d'en définir plein d'autres automatiquement. On peut donc définir un foncteur (avec une petite sélection de fonctions possibles) :