Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# explicit match vs function syntax

Tags:

syntax

f#

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"
    | _ -> "not 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?

like image 956
Benjol Avatar asked Dec 03 '09 10:12

Benjol


3 Answers

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]
like image 105
Stringer Avatar answered Dec 12 '22 14:12

Stringer


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.

like image 37
gradbot Avatar answered Dec 12 '22 13:12

gradbot


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 ??"
like image 34
Joshua Avatar answered Dec 12 '22 12:12

Joshua