Fonctions anonymes
On appelle fonction anonyme une fonction qui n'a pas de nom. De même que l'on utilise souvent des entiers ou des chaînes de caractères sans vouloir les nommer, on peut souhaiter avoir une fonction (souvent courte) sans lui donner de nom. La syntaxe des fonctions anonymes est : fun <arg1> <argn> -> <expression>
> fun x -> x + 1;; val it : int -> int = <fun:clo@0_3>
est une fonction anonyme qui ajoute 1 à son argument. Elle peut s'utiliser partout où une fonction classique peut être appelée.
> (fun x -> x + 1) 5;; val it : int = 6
Une fonction anonyme est une expression comme une autre.
> if 4 < 5 then fun x -> x + 1 else fun x -> x - 1;; val it : (int -> int) = <fun:it@18> > (if 4 < 5 then fun x -> x + 1 else fun x -> x - 1) 6;; val it : int = 7
Les deux définitions suivantes sont donc équivalentes :
> let next = fun x -> x + 1;; val next : int -> int > let next' x = x + 1;; val next' : int -> int
On peut voir la deuxième définition comme étant du sucre syntaxique (c'est-à-dire, un raccourci) pour la première.
Application partielle
Regardons la définition suivante :
> let add x = fun y -> x + y;; val add : int -> int -> int
La fonction a pour type int -> int -> int. La flèche est associative à droite, le type peut aussi s'écrire : int -> (int -> int). Une fonction qui prend un argument un entier et renvoie une fonction de type int -> int peut aussi être vue comme une fonction qui prend deux entiers en argument et renvoie un entier.
> let add x y = x + y;; // ce code est équivalent au précédent val add : int -> int -> int
Quelques exemples :
> let add' = add 4;; val add' : (int -> int) > add' 5;; val it : int = 9 > add 4 5;; val it : int = 9
D'une manière générale, toute fonction qui prend n arguments peut être appelée avec k arguments, k < n. Le résultat est une fonction qui prend k - n arguments. Cela s'appelle l'application partielle.
Voici un autre exemple avec les fonctions min et max, toutes deux définies dans la bibliothèque standard.
> let m = min 4;; val m : (int -> int) > m 6;; val it : int = 4 > m 2;; val it : int = 2
Les définitions suivantes sont équivalentes :
> let add x y = x + y;; val add : int -> int -> int > let add x = fun y -> x + y;; val add : int -> int -> int > let add = fun x -> fun y -> x + y;; val add : int -> int -> int > let add = fun x y -> x + y;; val add : int -> int -> int
Opérateurs
Si l'on a besoin d'utiliser un opérateur comme une expression classique, il suffit de le mettre en parenthèses :
> (+);; val it : (int -> int -> int) = <fun:it@46>
Un opérateur étant une fonction, on peut l'utiliser en notation préfixe (pour les amateurs de Lisp) :
> (+) 4 6;; val it : int = 10
Ou utiliser l'application partielle :
> (+) 4;; val it : (int -> int) = <fun:it@47>
On constate aussi que (+) est le nom de l'opérateur, c'est en effet un identifiant comme un autre. Il est donc possible, pour s'amuser, de redéfinir l'opérateur (+).
On redéfinit (+) localement :
> let (+) x y = x - y in 3 + 4;; val it : int = -1 > let (-) = (+) in 5 - 3;; val it : int = 8
Plus utile, et moins dangereux, on peut définir ses propres opérateurs :
> let (--) x y = abs (x - y);; val ( -- ) : int -> int -> int > 3 -- 5;; val it : int = 2
Les règles pour définir ses opérateurs sont un peu compliquées (concernant les noms valides, les priorités, la notion de préfixe/infixe), mais voici quelques exemples plus ou moins utiles :
> let (@-@) x y = x + " " + y;; val ( @-@ ) : string -> string -> string > "hello" @-@ "world";; val it : string = "hello world" > let (+) = 42 in 4 - (+);; val it : int = -38
By Laurent Le Brun, Saturday 10 November 2007 :: [FR] Cours F# :: #6



Comments
1. On Wednesday 4 March 2009 at 21:00, by Stéphane
2. On Thursday 5 March 2009 at 12:52, by Laurent
3. On Tuesday 1 September 2009 at 17:21, by larvor yann
4. On Tuesday 1 September 2009 at 21:24, by Laurent
5. On Wednesday 2 September 2009 at 16:39, by yann l'arvor
6. On Friday 20 November 2009 at 10:50, by Stéphane
7. On Friday 20 November 2009 at 16:30, by Laurent
Leave a comment