Désolé pour le titre vague, mais une partie de cette question est ce que ces deux styles de syntaxe sont appelés:
let foo1 x =
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
L'autre partie est la différence entre les deux, et quand je voudrais utiliser l'un ou l'autre?
La version de match s'appelle une "expression correspondante modèle". La version de la fonction s'appelle une "fonction de correspondance de modèle". Trouvé dans la section 6.6.4 du SPEC .
L'utilisation d'un sur l'autre est une question de style. Je préfère seulement utiliser la version de fonction lorsque j'ai besoin de définir une fonction qui n'est qu'une déclaration de match.
Le PRO pour la deuxième syntaxe est que lorsqu'il est utilisé dans une Lambda, il pourrait être un peu plus terres et lisible.
List.map (fun x -> match x with | 1 -> "one" | _ -> "not one") [0;1;2;3;1]
vs
List.map (function 1 -> "one" | _ -> "not one") [0;1;2;3;1]
La version de la fonction est une main courte pour la syntaxe de correspondance complète dans le cas particulier où l'instruction de correspondance est la fonction entière et la fonction ne dispose que d'un seul argument (Netples comptez en la fois). Si vous souhaitez avoir deux arguments, vous devez utiliser la syntaxe complète du match *. Vous pouvez le voir dans les types des deux fonctions suivantes.
//val match_test : string -> string -> string
let match_test x y = match x, y with
| "A", _ -> "Hello A"
| _, "B" -> "Hello B"
| _ -> "Hello ??"
//val function_test : string * string -> string
let function_test = function
| "A", _ -> "Hello A"
| _, "B" -> "Hello B"
| _ -> "Hello ??"
Comme vous pouvez le constater, la version de match prend deux arguments distincts, tandis que la version de la fonction prend un seul argument tuplé. J'utilise la version de la fonction pour la plupart des fonctions d'argument unique, car je trouve la syntaxe de fonction semble plus propre.
* Si vous vouliez vraiment, vous pouvez obtenir la version de la fonction pour avoir la bonne signature de type, mais il semble assez moche à mon avis - voir exemple ci-dessous.
//val function_match_equivalent : string -> string -> string
let function_match_equivalent x y = (x, y) |> function
| "A", _ -> "Hello A"
| _, "B" -> "Hello B"
| _ -> "Hello ??"
Ils font la même chose dans votre cas - le mot clé function
a agit comme une combinaison du mot-clé fun
(pour produire une lambda anonyme) suivie du mot-clé match
.
Donc, techniquement, ces deux sont les mêmes, avec l'ajout d'un fun
:
let foo1 = fun x ->
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
Juste pour l'assurance, je viens de recevoir à la page 321 de - expert fshaarp :
"Remarque, la liste 12-2 utilise le formulaire d'expression
function pattern-rules -> expression
. Cela équivaut à(fun x -> match x with pattern-rules -> expression)
et est particulièrement pratique comme moyen de définir des fonctions qui travaillent directement sur des syndicats discriminés. "
Fonction permet uniquement à un argument mais permet une correspondance de modèle, tandis que amusant est le moyen plus général et flexible de définir une fonction. Jetez un coup d'œil ici: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html
Les deux syntaxes sont équivalentes. La plupart des programmeurs choisissent l'un ou l'autre, puis l'utilisent de manière cohérente.
La première syntaxe reste plus lisible lorsque la fonction accepte plusieurs arguments avant de commencer à travailler.
C'est une vieille question mais je vais jeter ma 0,02 $.
En général, j'aime mieux la version match
depuis que je viens du Python world où "explicite est meilleur que implicite".
Bien sûr, si les informations de type sur le paramètre sont nécessaires, la version function
ne peut pas être utilisée.
Otoh j'aime l'argument fabriqué par Stringer
donc je vais commencer à utiliser function
dans des simples lambdas.