En première approximation, le filtrage par motifs ressemble à une version dopée du switch des langages tels que C. La différence est que le filtrage permet d'observer bien plus que les entiers : on peut observer toute valeur construite, c'est-à-dire toute valeur qui n'est pas une fonction (ni un objet ou un module, mais nous manipulerons très peu voire pas de valeurs de types objets ou modules).
Tous les motifs doivent correspondre à la construction de valeurs de même type.
Toutes les constructions possibles du type de la valeur observée doivent être testées.
Les motifs peuvent être arbitrairement profonds.
les expressions calculées pour chaque motif, situées après les flèches ->, doivent toutes avoir le même type. Ce type est le type de l'expression complète de filtrage par motifs.
Les motifs sont testés dans l'ordre de haut en bas. Si plusieurs motifs permettent l'observation de la valeur, le plus haut sera choisi.
Tout identifiant dans un motif correspond à une nouvelle abstraction. On ne peut donc pas tester l'égalité avec une variable dans un motif.
Chaque identifiant ne peut apparaître qu'une fois par motif (même règle que dans les arguments d'une fonction).
le mot-clé when permet d'ajouter une condition booléenne à un motif. Le motif n'est choisi que si l'expression booléenne s'évalue à true.
le mot-clé as permet de nommer une partie bien formée d'un motif.
Les motifs peuvent aussi être utilisés en argument des fonctions. Un problème potentiel dans ce cas est qu'un argument prend la forme d'un seul motif, donc ne peut correspondre qu'à une partie des constructions possibles, alors que le filtrage par motifs permet de définir plusieurs motifs couvrant tous les cas de constructions possibles. Dans ce cas, la seule solution est d'abstraire l'argument par une variable, puis de faire un filtrage par motif de cette variable. En fait, c'est une forme si fréquente qu'OCaml propose une syntaxe adaptée, pour prendre un argument et immédiatement le filtrer :
function est simplement l'abbréviation de fun x -> match x with.
Enfin, il est fréquent de vouloir observer deux valeurs ou plus simultanément. On pourrait observer la première, puis dans chaque cas d'observation comparer la deuxième, etc. Le problème est que la syntaxe devient très vite illisible. En général on s'interdira de filtrer par motifs dans un cas d'observation d'un autre filtrage par motifs : pas d'imbrication des filtrages par motifs !
Pour filtrer simultanément plusieurs valeurs, la solution est simple : il suffit de filtrer le tuple construit avec toutes ces valeurs :
Une autre règle pour garder les filtrages par motifs compréhensibles est de garder l'expression calculée dans chaque cas d'observation simple. Dans l'idéal, cette expression sera soit la construction d'une valeur, soit une abstraction (une variable), soit l'appel d'une fonction correctement nommée. Les calculs plus complexes sont donc déléguées à une fonction en dehors du filtrage. Il faut garder à l'esprit qu'un filtrage par motif doit pouvoir être lu aisément : les différents cas et les actions effectuées pour chaque cas doivent se comprendre en première lecture.
Les types élémentaires peuvent aussi être observé. Tout littéral est un motif possible, par exemple 42, 3.14, true, "foobar".
Les fonctions peuvent être observées, mais elles ne sont pas construites au sens où les autres valeurs sont construites, donc la seule façon de les observer est de leur donner un nom.
Nous utilisons et continuerons à utiliser des types dont nous ne connaissons pas la définition. Ce sont des types abstraits. Comme les fonctions, la seule observation possible d'une valeur d'un type abstrait est de la nommer.