开发者

F# explicit match vs function syntax

Sorry about the vague title, but part of this question is what these two syntax styles are called:

let foo1 x = 
    match x with
    | 1 -> "one"
    | _ -> "n开发者_如何学Cot one"

let foo2 = function 
    | 1 -> "one" 
    | _ -> "not one"

The other part is what difference there is between the two, and when I would want to use one or the other?


The pro for the second syntax is that when used in a lambda, it could be a bit more terse and readable.

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]


The match version is called a "pattern matching expression". The function version is called a "pattern matching function". Found in section 6.6.4 of the spec.

Using one over the other is a matter of style. I prefer only using the function version when I need to define a function that is only a match statement.


The function version is a short hand for the full match syntax in the special case where the match statement is the entire function and the function only has a single argument (tuples count as one). If you want to have two arguments then you need to use the full match syntax*. You can see this in the types of the following two functions.

//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 ??"

As you can see match version takes two separate arguments whereas the function version takes a single tupled argument. I use the function version for most single argument functions since I find the function syntax looks cleaner.

*If you really wanted to you can get the function version to have the right type signature but it looks pretty ugly in my opinion - see example below.

//val function_match_equivalent : string -> string -> string
let function_match_equivalent x y = (x, y) |> function
                                                | "A", _ -> "Hello A"
                                                | _, "B" -> "Hello B"
                                                | _ -> "Hello ??"


They do the same thing in your case -- the function keyword acts like a combination of the fun keyword (to produce an anonymous lambda) followed by the match keyword.

So technically these two are the same, with the addition of a fun:

let foo1 = fun x ->
    match x with
    | 1 -> "one"
    | _ -> "not one"

let foo2 = function
    | 1 -> "one"
    | _ -> "not one"


Just for completeness sake, I just got to page 321 of Expert FSharp:

"Note, Listing 12-2 uses the expression form function pattern-rules -> expression. This is equivalent to (fun x -> match x with pattern-rules -> expression) and is especially convenient as a way to define functions working directly over discriminated unions."


function only allows for one argument but allows for pattern matching, while fun is the more general and flexible way to define a function. Take a look here: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html


The two syntaxes are equivalent. Most programmers choose one or the other and then use it consistently.

The first syntax remains more readable when the function accepts several arguments before starting to work.


This is an old question but I will throw my $0.02.

In general I like better the match version since I come from the Python world where "explicit is better than implicit."

Of course if type information on the parameter is needed the function version cannot be used.

OTOH I like the argument made by Stringer so I will start to use function in simple lambdas.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜