🕷️ Crawler Inspector

URL Lookup

Direct Parameter Lookup

Raw Queries and Responses

1. Shard Calculation

Query:
Response:
Calculated Shard: 35 (from laksa167)

2. Crawled Status Check

Query:
Response:

3. Robots.txt Check

Query:
Response:

4. Spam/Ban Check

Query:
Response:

5. Seen Status Check

ℹ️ Skipped - page is already crawled

📄
INDEXABLE
CRAWLED
17 hours ago
🤖
ROBOTS ALLOWED

Page Info Filters

FilterStatusConditionDetails
HTTP statusPASSdownload_http_code = 200HTTP 200
Age cutoffPASSdownload_stamp > now() - 6 MONTH0 months ago
History dropPASSisNull(history_drop_reason)No drop reason
Spam/banPASSfh_dont_index != 1 AND ml_spam_score = 0ml_spam_score=0
CanonicalPASSmeta_canonical IS NULL OR = '' OR = src_unparsedNot set

Page Details

PropertyValue
URLhttps://coherentpdf.com/tmp/modules.fr.html
Last Crawled2026-04-12 07:00:12 (17 hours ago)
First Indexed2025-03-20 14:41:02 (1 year ago)
HTTP Status Code200
Meta TitleModules – OCaml
Meta Descriptionnull
Meta Canonicalnull
Boilerpipe Text
Usage standard Avec OCaml, tout programme est contenu dans un module. Un module peut même être, plus rarement, un sous-module d'un autre, à la manière d'une arborescence de dossiers imbriqués les uns dans les autres. Lorsqu'on écrit un programme, avec par exemple deux fichiers amodule.ml et bmodule.ml , ceux ci définissent deux modules, intitulés respectivement Amodule et Bmodule , possédant le même contenu que nos fichiers. Prenons par exemple le fichier amodule.ml suivant : let hello () = print_endline "Hello" ainsi que le fichier bmodule.ml : Amodule .hello () En général, les fichiers sont compilés un par un, comme ceci : ocamlopt -c amodule.ml ocamlopt -c bmodule.ml ocamlopt -o hello amodule.cmx bmodule.cmx Nous avons à présent un petit exécutable pouvant afficher « Hello ». Comme on l'a constaté, on accède à n'importe quoi dans un module donné en appelant le nom du module (qui commence toujours par une majuscule) suivi d'un point et du nom de l'objet utilisé. Cet objet peut être une variable, un type ou tout autre chose définie au sein du module. Les librairies (bibliothèques), notament la bibliothèque standard, fournit un certain nombre de modules. Par exemple, List.iter désigne la fonction iter définie au sein du module List . Si jamais on souhaite utiliser de façon intensive un module, on peut désirer se passer de l'appel de son nom; il suffit pour cela d'utiliser l'instruction open . En poursuivant notre exemple, bmodule.ml pourrait contenir : open Amodule ;; hello () Notons que beaucoup de programmeurs « oublient » les ;; , il est plus courant d'écrire open Amodule let _ = hello () L'usage de l'instruction open n'est qu'une question de goût. Certains modules proposent des noms déjà utilisés dans d'autres modules. Ainsi le module List contient des fonctions aux noms assez courants dans les autres modules, aussi on n'écrit assez rarement open List . D'autres comme Printf utilise des noms très spécifiques, suffisament rares pour ne pas créer de conflits avec d'autres modules; pour éviter d'écrire Printf.printf on préfera utiliser open Printf en début de fichier : open Printf let my_data = [ "a" ; "beautiful" ; "day" ] let _ = List .iter ( fun s -> printf "%s\n" s) my_data Interfaces modulaires et signatures. Un module peut fournir un grand nombre d'éléments (fonctions, types, sous modules, variables...) au programme qui l'utilise. Par défaut, tous les objets définis au sein du module seront accessibles depuis « l'extérieur ». Ceci peut être utile dans de petits programmes, mais il est préférable qu'un module ne propose que ce qu'il est conçu pour proposer, sans le fouillis des fonctions auxiliaires ou variables temporaires. Pour cela, nous pouvons définir une interface modulaire, qui se comporte comme un filtre entourant le module. De la même façon qu'un module vient d'un fichier .ml , l'interface corespondante (et sa signature) viennent d'un fichier .mli . Il contient la liste des valeurs avec leur type (ou signature pour les fonctions). Réécrivons notre amodule.ml  : let message = "Hello" let hello () = print_endline message Tel quel, l'interface de Amodule est la suivante : val message : string val hello : unit -> unit Supposons que nous souhaitions que personne de l'exterieur ne puisse accéder à la variable message . Alors, nous choisissons de la « cacher » en créant une interface restreinte; le amodule.mli est alors : val hello : unit -> unit (** Displays a greeting message. *) (Notons que commenter les fichiers .mli en utilisant le format d' ocamldoc est une très bonne habitude à prendre). Les fichiers .mli doivent être compilés juste avant les .ml correspondants. On peut les compiler à l'aide d' ocamlc , même si les .ml sont écrit en code natif avec ocamlopt . ocamlc -c amodule.mli ocamlopt -c amodule.ml ... Types abstraits (virtuels) Passons à présent aux définitions de types. Nous avons vu que les valeurs telles que les fonctions, peuvent être exportées en donnant leur noms et signatures dans un fichier .mli , par exemple : val hello : unit -> unit Cependant, on définit souvent au sein d'un module de nouveaux types. Prenons par exemple un enregistrement d'une date : type date = { day : int; month : int; year : int } Il n'y a plus 2 mais 4 options possibles dans l'écriture du fichier .mli  : Le type n'est pas précisé dans le .mli La définition du type est copiée-collée dans le .mli Le type est rendu virtuel, seul son nom est précisé. (il est connu du compilateur mais on ne peut y toucher) Les champs d'un enregistrement sont rendus seulement lisibles et non plus modifiables (lecture seule) type date = private { ... } . Dans le troisieme cas, on obtient le code suivant : type date Les utilisateurs de ce module peuvent désormais manipuler des données de type date mais ne peuvent accéder aux champs de l'enregistrement, seules les fonctions du modules sont autorisées à le faire. Supposons que notre module contienne trois fonctions, une pour créer une date, une pour calculer la différence entre deux dates et une pour convertir une date en années : type date val create : ?days:int -> ?months:int -> ?years:int -> unit -> date val sub : date -> date -> date val years : date -> float On remarque alors que seuls create et sub peuvent être utilisés pour créer des enregistrements de dates. Il n'est ainsi pas possible pour l'utilisateur de créer des enregistrements difformes. Il s'ensuit que, bien que notre implémentation utilise un enregistrement, nous pouvons le modifier sans qu'aucun fichier utilisant ce module n'en soit perturbé. Ceci est particulièrement utile dans le cas des librairies, qui peuvent ainsi être modifiées tout en gardant une utilisation identique. Sous modules Création d'un sous module Nous avons vu qu'un fichier unique exemple.ml se compilait un un module unique Exemple . Sa signature est automatiquement générée et est la plus exhaustive possible, sauf si elle est restreinte par l'écriture d'un fichier .mli . Ceci dit, un module donné peut être défini explicitement au sein même d'un fichier, il est ainsi un sous module du module principal. Prenons l'exemple suivant : module Hello = struct let message = "Hello" let hello () = print_endline message end let goodbye () = print_endline "Goodbye" let hello_goodbye () = Hello .hello (); goodbye () Depuis un autre fichier, nous avons désormais deux niveaux de modules. Nous pouvons écrire alors : let () = Example . Hello .hello (); Example .goodbye () Interface submodulaire Nous pouvons de même restreindre l'interface d'un sous module. On appelle cela un type modulaire. Dans notre exemple.ml cela donne : module Hello : sig val hello : unit -> unit end = struct let message = "Hello" let hello () = print_endline message end (* At this point, Hello .message is not accessible anymore. *) let goodbye () = print_endline "Goodbye" let hello_goodbye () = Hello .hello (); goodbye () La définition du module Hello est équivalente au couple de fichiers hello.mli/hello.ml . Cependant, écrire tout cela dans un même bloc de code n'est pas très élégant, nous préférons donc définir la signature séparement. module type Hello_type = sig val hello : unit -> unit end module Hello : Hello_type = struct ... end Hello_type est un type modulaire et peut donc être réutilisé pour définir d'autres interfaces de modules. Bien que l'utilisation des sous modules peut se révéler pratique dans certains cas spécifiques, leur utilité réelle se révèle avec les foncteurs, développés dans la section suivante. Foncteurs Les foncteurs sont probablement une des fonctionnalités les plus complexes d'OCaml, même s'il n'est pas nécessaire de les utiliser de façon intensive pour être un bon programmeur. En réalité, il est possible que nous n'ayons jamais à définir nous-mêmes de foncteurs, mais nous serons sûrement appelés à les rencontrer dans la librairie standard. Ils sont la seule façon d'utiliser les modules Set et Map , mais leur utilisation reste à notre portée. Un foncteur est un module qui est paramétré par un autre module, tout comme une fonction n'est qu'une valeur paramétrée par d'autres valeurs (les arguments). En gros, cela permet de paramétrer un type par une valeur, ce qui est impossible à faire directement en OCaml. Par exemple, nous pourrions définir un foncteur prenant un entier n et retournant un ensemble d'opérations sur des tableaux de longeurs n uniquement. Si par erreur, un programmeur donne un tableau normal à une de ces fonctions, le compilateur soulèvera une erreur. Si nous n'utilisions pas un foncteur mais le type standard des tableaux, le compilateur ne sera pas capable de détecter l'erreur, et nous obtiendrions une erreur à l'exécution bien après la compilation, ce qui est bien pire ! La librairie standard définit le module Set , qui fournit un foncteur Make . Ce foncteur requiert un argument, qui est un module contenant (au moins) deux choses : le type des éléments donné par t et la fonction de comparaison donnée par compare . L'important est de s'assurer que la même fonction de comparaison sera toujours utilisée, même si le programmeur commet une erreur. Par exemple, si nous voulons un ensemble d'entiers, il faut utiliser ceci : module Int_set = Set .Make ( struct type t = int let compare = compare end ) Pour les ensembles de chaînes, cela est même plus simple car la librairie standard fournit un module String avec un type t et une fonction compare . On peut donc créer, à peu de frais, un module pour la manipulation des ensembles de chaînes de caractères : module String_set = Set .Make (String) (les parenthèses sont obligatoires !) Un foncteur avec un argument peut être défini comme ceci : module F (X : X_type) = struct ... end où X est le module passé en argument, et X\_type est sa signature, qui est obligatoire. La signature du module obtenu peut elle même être restreinte à l'aide la syntaxe habituelle : module F (X : X_type) : Y_type = struct ... end ou bien en le spécifiant dans le fichier .mli : module F (X : X_type) : Y_type La syntaxe des foncteurs reste cependant difficile à assimiler. Il est donc préférable de jeter un coup d'oeil aux fichier sources set.ml ou map.ml dans la librairie standard. Une dernière remarque : les foncteurs ont été conçus pour aider les programmeurs et non pas pour améliorer les performances. L'exécution est même plus lente, à moins d'utiliser un défoncteur comme ocamldefun , qui requiert un accès au code source du foncteur. Manipulation pratique des modules Afficher l'interface d'un module En toplevel , il est possible de visualiser le contenu d'un module en tapant : module M = List On obtient alors : # module M = List ;; module M = List De toute façon, il existe une documentation pour la plupart des modules (on peut aussi utiliser ocamlbrowser , fourni avec labltk ). Insertion dans un module Supposons que nous sentions qu'une fonction manque au module standard List et que nous désirions qu'elle en fasse partie intégrante. Il est possible d'utiliser l'instruction include au sein d'un fichier extensions.ml afin d'insérer notre fonction : module List = struct include List let rec optmap f = function | [] -> [] | hd :: tl -> match f hd with | None -> optmap f tl | Some x -> x :: optmap f tl end Nous avons créé un nouveau module Extensions.List contenant , en plus des fonctions habituelles du module List , une nouvelle fonction optmap . Depuis un autre fichier, il nous suffit d'ouvrir notre module Extensions pour que celui-ci « écrase » le module List standard : open Extensions ... List .optmap ...
Markdown
[![OCaml](https://coherentpdf.com/img/colour-logo-white.svg)![OCaml](https://coherentpdf.com/img/colour-logo-white.png)](https://coherentpdf.com/index.fr.html) - [Apprendre](https://coherentpdf.com/learn/index.fr.html) - [Documentation](https://coherentpdf.com/docs/index.fr.html) - [Paquets](https://opam.ocaml.org/) - [Communauté](https://coherentpdf.com/community/index.fr.html) - [Actualités](https://coherentpdf.com/community/planet/) [Éditer cette page](https://github.com/ocaml/ocaml.org/tree/master/site/learn/tutorials/modules.fr.md "Éditer cette page") 1. [Home](https://coherentpdf.com/) 2. [Apprendre](https://coherentpdf.com/learn/index.fr.html) 3. [Tutoriel OCaml](https://coherentpdf.com/learn/tutorials/index.fr.html) 4. Modules - [en](https://coherentpdf.com/tmp/modules.html) - fr - [日本語](https://coherentpdf.com/tmp/modules.ja.html) - [한국어](https://coherentpdf.com/tmp/modules.ko.html) - [中文](https://coherentpdf.com/tmp/modules.zh.html) - [Contenu](https://coherentpdf.com/tmp/modules.fr.html) - [Usage standard](https://coherentpdf.com/tmp/modules.fr.html#Usage-standard) - [Interfaces modulaires et signatures.](https://coherentpdf.com/tmp/modules.fr.html#Interfaces-modulaires-et-signatures) - [Types abstraits (virtuels)](https://coherentpdf.com/tmp/modules.fr.html#Types-abstraits-virtuels) - [Sous modules](https://coherentpdf.com/tmp/modules.fr.html#Sous-modules) - [Création d'un sous module](https://coherentpdf.com/tmp/modules.fr.html#Cr-ation-d-39-un-sous-module) - [Foncteurs](https://coherentpdf.com/tmp/modules.fr.html#Foncteurs) - [Comment utiliser un foncteur ?](https://coherentpdf.com/tmp/modules.fr.html#Comment-utiliser-un-foncteur) - [Comment définir un foncteur ?](https://coherentpdf.com/tmp/modules.fr.html#Comment-d-finir-un-foncteur) - [Manipulation pratique des modules](https://coherentpdf.com/tmp/modules.fr.html#Manipulation-pratique-des-modules) - [Afficher l'interface d'un module](https://coherentpdf.com/tmp/modules.fr.html#Afficher-l-39-interface-d-39-un-module) - [Insertion dans un module](https://coherentpdf.com/tmp/modules.fr.html#Insertion-dans-un-module) ``` ``` \# # Modules ## Usage standard Avec OCaml, tout programme est contenu dans un module. Un module peut même être, plus rarement, un sous-module d'un autre, à la manière d'une arborescence de dossiers imbriqués les uns dans les autres. Lorsqu'on écrit un programme, avec par exemple deux fichiers `amodule.ml` et `bmodule.ml`, ceux ci définissent deux modules, intitulés respectivement `Amodule` et `Bmodule`, possédant le même contenu que nos fichiers. Prenons par exemple le fichier amodule.ml suivant : ``` let hello () = print_endline "Hello" ``` ainsi que le fichier bmodule.ml : ``` Amodule.hello () ``` En général, les fichiers sont compilés un par un, comme ceci : ``` ocamlopt -c amodule.ml ocamlopt -c bmodule.ml ocamlopt -o hello amodule.cmx bmodule.cmx ``` Nous avons à présent un petit exécutable pouvant afficher « Hello ». Comme on l'a constaté, on accède à n'importe quoi dans un module donné en appelant le nom du module (qui commence toujours par une majuscule) suivi d'un point et du nom de l'objet utilisé. Cet objet peut être une variable, un type ou tout autre chose définie au sein du module. Les librairies (bibliothèques), notament la bibliothèque standard, fournit un certain nombre de modules. Par exemple, `List.iter` désigne la fonction `iter` définie au sein du module `List`. Si jamais on souhaite utiliser de façon intensive un module, on peut désirer se passer de l'appel de son nom; il suffit pour cela d'utiliser l'instruction `open`. En poursuivant notre exemple, `bmodule.ml` pourrait contenir : ``` open Amodule;; hello () ``` Notons que beaucoup de programmeurs « oublient » les `;;`, il est plus courant d'écrire ``` open Amodule let _ = hello () ``` L'usage de l'instruction `open` n'est qu'une question de goût. Certains modules proposent des noms déjà utilisés dans d'autres modules. Ainsi le module `List` contient des fonctions aux noms assez courants dans les autres modules, aussi on n'écrit assez rarement `open List`. D'autres comme `Printf` utilise des noms très spécifiques, suffisament rares pour ne pas créer de conflits avec d'autres modules; pour éviter d'écrire `Printf.printf` on préfera utiliser `open Printf` en début de fichier : ``` open Printf let my_data = [ "a"; "beautiful"; "day" ] let _ = List.iter (fun s -> printf "%s\n" s) my_data ``` ## Interfaces modulaires et signatures. Un module peut fournir un grand nombre d'éléments (fonctions, types, sous modules, variables...) au programme qui l'utilise. Par défaut, tous les objets définis au sein du module seront accessibles depuis « l'extérieur ». Ceci peut être utile dans de petits programmes, mais il est préférable qu'un module ne propose que ce qu'il est conçu pour proposer, sans le fouillis des fonctions auxiliaires ou variables temporaires. Pour cela, nous pouvons définir une interface modulaire, qui se comporte comme un filtre entourant le module. De la même façon qu'un module vient d'un fichier `.ml`, l'interface corespondante (et sa signature) viennent d'un fichier `.mli`. Il contient la liste des valeurs avec leur type (ou signature pour les fonctions). Réécrivons notre `amodule.ml` : ``` let message = "Hello" let hello () = print_endline message ``` Tel quel, l'interface de `Amodule` est la suivante : ``` val message : string val hello : unit -> unit ``` Supposons que nous souhaitions que personne de l'exterieur ne puisse accéder à la variable `message`. Alors, nous choisissons de la « cacher » en créant une interface restreinte; le `amodule.mli` est alors : ``` val hello : unit -> unit (** Displays a greeting message. *) ``` (Notons que commenter les fichiers `.mli` en utilisant le format d'`ocamldoc` est une très bonne habitude à prendre). Les fichiers `.mli` doivent être compilés juste avant les `.ml` correspondants. On peut les compiler à l'aide d'`ocamlc`, même si les `.ml`sont écrit en code natif avec `ocamlopt`. ``` ocamlc -c amodule.mli ocamlopt -c amodule.ml ... ``` ## Types abstraits (virtuels) Passons à présent aux définitions de types. Nous avons vu que les valeurs telles que les fonctions, peuvent être exportées en donnant leur noms et signatures dans un fichier `.mli`, par exemple : ``` val hello : unit -> unit ``` Cependant, on définit souvent au sein d'un module de nouveaux types. Prenons par exemple un enregistrement d'une date : ``` type date = { day : int; month : int; year : int } ``` Il n'y a plus 2 mais 4 options possibles dans l'écriture du fichier `.mli` : 1. Le type n'est pas précisé dans le `.mli` 2. La définition du type est copiée-collée dans le `.mli` 3. Le type est rendu virtuel, seul son nom est précisé. (il est connu du compilateur mais on ne peut y toucher) 4. Les champs d'un enregistrement sont rendus seulement lisibles et non plus modifiables (lecture seule) `type date = private { ... }`. Dans le troisieme cas, on obtient le code suivant : ``` type date ``` Les utilisateurs de ce module peuvent désormais manipuler des données de type `date` mais ne peuvent accéder aux champs de l'enregistrement, seules les fonctions du modules sont autorisées à le faire. Supposons que notre module contienne trois fonctions, une pour créer une date, une pour calculer la différence entre deux dates et une pour convertir une date en années : ``` type date val create : ?days:int -> ?months:int -> ?years:int -> unit -> date val sub : date -> date -> date val years : date -> float ``` On remarque alors que seuls `create` et `sub` peuvent être utilisés pour créer des enregistrements de dates. Il n'est ainsi pas possible pour l'utilisateur de créer des enregistrements difformes. Il s'ensuit que, bien que notre implémentation utilise un enregistrement, nous pouvons le modifier sans qu'aucun fichier utilisant ce module n'en soit perturbé. Ceci est particulièrement utile dans le cas des librairies, qui peuvent ainsi être modifiées tout en gardant une utilisation identique. ## Sous modules ### Création d'un sous module Nous avons vu qu'un fichier unique `exemple.ml` se compilait un un module unique `Exemple`. Sa signature est automatiquement générée et est la plus exhaustive possible, sauf si elle est restreinte par l'écriture d'un fichier `.mli`. Ceci dit, un module donné peut être défini explicitement au sein même d'un fichier, il est ainsi un sous module du module principal. Prenons l'exemple suivant : ``` module Hello = struct let message = "Hello" let hello () = print_endline message end let goodbye () = print_endline "Goodbye" let hello_goodbye () = Hello.hello (); goodbye () ``` Depuis un autre fichier, nous avons désormais deux niveaux de modules. Nous pouvons écrire alors : ``` let () = Example.Hello.hello (); Example.goodbye () ``` #### Interface submodulaire Nous pouvons de même restreindre l'interface d'un sous module. On appelle cela un type modulaire. Dans notre `exemple.ml` cela donne : ``` module Hello : sig val hello : unit -> unit end = struct let message = "Hello" let hello () = print_endline message end (* At this point, Hello.message is not accessible anymore. *) let goodbye () = print_endline "Goodbye" let hello_goodbye () = Hello.hello (); goodbye () ``` La définition du module `Hello` est équivalente au couple de fichiers `hello.mli/hello.ml`. Cependant, écrire tout cela dans un même bloc de code n'est pas très élégant, nous préférons donc définir la signature séparement. ``` module type Hello_type = sig val hello : unit -> unit end module Hello : Hello_type = struct ... end ``` `Hello_type` est un type modulaire et peut donc être réutilisé pour définir d'autres interfaces de modules. Bien que l'utilisation des sous modules peut se révéler pratique dans certains cas spécifiques, leur utilité réelle se révèle avec les foncteurs, développés dans la section suivante. ## Foncteurs Les foncteurs sont probablement une des fonctionnalités les plus complexes d'OCaml, même s'il n'est pas nécessaire de les utiliser de façon intensive pour être un bon programmeur. En réalité, il est possible que nous n'ayons jamais à définir nous-mêmes de foncteurs, mais nous serons sûrement appelés à les rencontrer dans la librairie standard. Ils sont la seule façon d'utiliser les modules `Set` et `Map`, mais leur utilisation reste à notre portée. Un foncteur est un module qui est paramétré par un autre module, tout comme une fonction n'est qu'une valeur paramétrée par d'autres valeurs (les arguments). En gros, cela permet de paramétrer un type par une valeur, ce qui est impossible à faire directement en OCaml. Par exemple, nous pourrions définir un foncteur prenant un entier `n` et retournant un ensemble d'opérations sur des tableaux de longeurs `n` uniquement. Si par erreur, un programmeur donne un tableau normal à une de ces fonctions, le compilateur soulèvera une erreur. Si nous n'utilisions pas un foncteur mais le type standard des tableaux, le compilateur ne sera pas capable de détecter l'erreur, et nous obtiendrions une erreur à l'exécution bien après la compilation, ce qui est bien pire \! ### Comment utiliser un foncteur ? La librairie standard définit le module `Set`, qui fournit un foncteur `Make`. Ce foncteur requiert un argument, qui est un module contenant (au moins) deux choses : le type des éléments donné par `t` et la fonction de comparaison donnée par `compare`. L'important est de s'assurer que la même fonction de comparaison sera toujours utilisée, même si le programmeur commet une erreur. Par exemple, si nous voulons un ensemble d'entiers, il faut utiliser ceci : ``` module Int_set = Set.Make (struct type t = int let compare = compare end) ``` Pour les ensembles de chaînes, cela est même plus simple car la librairie standard fournit un module `String` avec un type `t` et une fonction `compare`. On peut donc créer, à peu de frais, un module pour la manipulation des ensembles de chaînes de caractères : ``` module String_set = Set.Make (String) ``` (les parenthèses sont obligatoires !) ### Comment définir un foncteur ? Un foncteur avec un argument peut être défini comme ceci : ``` module F (X : X_type) = struct ... end ``` où `X` est le module passé en argument, et `X\_type` est sa signature, qui est obligatoire. La signature du module obtenu peut elle même être restreinte à l'aide la syntaxe habituelle : ``` module F (X : X_type) : Y_type = struct ... end ``` ou bien en le spécifiant dans le fichier `.mli` : ``` module F (X : X_type) : Y_type ``` La syntaxe des foncteurs reste cependant difficile à assimiler. Il est donc préférable de jeter un coup d'oeil aux fichier sources `set.ml` ou `map.ml` dans la librairie standard. Une dernière remarque : les foncteurs ont été conçus pour aider les programmeurs et non pas pour améliorer les performances. L'exécution est même plus lente, à moins d'utiliser un défoncteur comme `ocamldefun`, qui requiert un accès au code source du foncteur. ## Manipulation pratique des modules ### Afficher l'interface d'un module En `toplevel`, il est possible de visualiser le contenu d'un module en tapant : ``` module M = List ``` On obtient alors : ``` # module M = List;; module M = List ``` De toute façon, il existe une documentation pour la plupart des modules (on peut aussi utiliser `ocamlbrowser`, fourni avec `labltk`). ### Insertion dans un module Supposons que nous sentions qu'une fonction manque au module standard `List` et que nous désirions qu'elle en fasse partie intégrante. Il est possible d'utiliser l'instruction `include` au sein d'un fichier `extensions.ml` afin d'insérer notre fonction : ``` module List = struct include List let rec optmap f = function | [] -> [] | hd :: tl -> match f hd with | None -> optmap f tl | Some x -> x :: optmap f tl end ``` Nous avons créé un nouveau module `Extensions.List` contenant , en plus des fonctions habituelles du module `List`, une nouvelle fonction `optmap`. Depuis un autre fichier, il nous suffit d'ouvrir notre module `Extensions` pour que celui-ci « écrase » le module `List` standard : ``` open Extensions ... List.optmap ... ``` # [Apprendre](https://coherentpdf.com/learn/index.fr.html) - [Exemples de code](https://coherentpdf.com/learn/taste.fr.html) - [Tutoriels](https://coherentpdf.com/learn/tutorials/index.fr.html) - [Livres](https://coherentpdf.com/learn/books.html) - [Cas d'usage](https://coherentpdf.com/learn/success.fr.html) # [Documentation](https://coherentpdf.com/docs/index.fr.html) - [Installer OCaml](https://coherentpdf.com/docs/install.fr.html) - [Manuel](http://caml.inria.fr/pub/docs/manual-ocaml/) - [Paquets](https://opam.ocaml.org/packages/) - [Compiler Releases](https://coherentpdf.com/releases/index.fr.html) - [Logos](https://coherentpdf.com/docs/logos.html) # [Communauté](https://coherentpdf.com/community/index.fr.html) - [Lieux de discussion](https://coherentpdf.com/community/mailing_lists.fr.html) - [Rencontres](https://coherentpdf.com/meetings/index.fr.html) - [Actualités](https://coherentpdf.com/community/planet/) - [Support](https://coherentpdf.com/community/support.fr.html) - [Signaler un bug d'OCaml](http://caml.inria.fr/mantis/my_view_page.php) # Site Web - [Éditer cette page](https://github.com/ocaml/ocaml.org/tree/master/site/learn/tutorials/modules.fr.md) - [Problèmes du site Web](https://github.com/ocaml/ocaml.org/issues) - [À propos de ce site](https://coherentpdf.com/about.fr.html) - [Dépôt GitHub](https://github.com/ocaml/ocaml.org/) - [Crédits](https://coherentpdf.com/contributors.fr.html)
Readable Markdownnull
Shard35 (laksa)
Root Hash11981928348964667835
Unparsed URLcom,coherentpdf!/tmp/modules.fr.html s443