Si vous écrivez [x]
une liste à un élément, c'est l'abréviation de (x : [])
ou encore plus verbeux (:) x []
. Il s'agit donc d'un "contre" ( (:)
) avec x
comme élément, et la liste vide comme queue.
Donc votre fonction f (x:xs)
correspondra en effet à une liste comportant un (ou plusieurs) éléments. Pour une liste avec un élément, x
sera l'élément, et xs
une liste vide.
ne correspondrait pas, car le motif (x:xs)
ne correspond que s'il y a plus d'éléments xs
après le x
dans la liste, ce qui n'est pas le cas pour la liste [1]
.
Non, le (x:xs)
correspond à chaque non vide liste, avec x
le premier élément de la liste, et xs
une liste (éventuellement vide) des éléments restants.
Si vous souhaitez ne faire correspondre que des listes comportant, par exemple, deux éléments ou plus. Vous pouvez les faire correspondre avec :
-- two or more elements
f (x1 : x2 : xs) = …
Ici x1
y x2
correspondra respectivement au premier et au deuxième élément de la liste, et xs
est une liste qui contient les éléments restants.
EDIT : pour répondre vos commentaires :
Je me demande pourquoi ma définition de fonction ne compile même pas en premier lieu, parce que le type de fonction est [Int] -> [Int]
donc si je lui donne la liste vide, alors ce n'est pas [Int]
en conséquence, n'est-ce pas ?
La liste vide []
est l'un des constructeurs de données de la [a]
ce qui signifie que []
a un type [] :: [a]
. Il peut correspondre à la variable de type a
avec Int
et donc []
peut avoir le type [] :: [Int]
.
Ensuite, comment faire correspondre une liste contenant exactement deux éléments ? [a, b]
?
Vous pouvez faire correspondre cette liste avec :
f (a : b : []) = …
ou vous pouvez l'assortir avec :
f [a, b] = …
Les deux sont équivalents. [a, b]
es sucre syntaxique : il est remplacé par le compilateur par (a : b : [])
mais pour les humains, il est bien sûr plus pratique de travailler avec [a, b]
.