简体   繁体   English

F#显式匹配vs函数语法

[英]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"
    | _ -> "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? 另一部分是两者之间的区别,当我想要使用其中一个时?

The pro for the second syntax is that when used in a lambda, it could be a bit more terse and readable. 第二种语法的专业版是,当在lambda中使用时,它可能更简洁和可读。

List.map (fun x -> match x with | 1 -> "one" | _ -> "not one") [0;1;2;3;1]

vs 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 . 规范 6.6.4节。

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). 在特殊情况下,函数版本是完全匹配语法的简写,其中match语句是整个函数,函数只有一个参数(元组计数为1)。 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. 如您所见,匹配版本采用两个单独的参数,而函数版本采用单个tupled参数。 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. 它们在您的情况下执行相同的操作 - function关键字的作用类似于fun关键字(生成匿名lambda)后跟match关键字的组合。

So technically these two are the same, with the addition of a fun : 所以在技术上这两个是相同的,增加了一个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 : 为了完整起见,我得到了Expert FSharp的第321页:

"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." “注意,清单12-2使用表达式形式function pattern-rules -> expression 。这相当于(fun x -> match x with pattern-rules -> expression) ,并且特别方便定义函数直接工作过度歧视的工会。“

function only allows for one argument but allows for pattern matching, while fun is the more general and flexible way to define a function. 函数只允许一个参数但允许模式匹配,而fun是定义函数的更通用和灵活的方法。 Take a look here: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html 看看这里: 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. 这是一个老问题,但我会扔掉0.02美元。

In general I like better the match version since I come from the Python world where "explicit is better than implicit." 总的来说,我更喜欢match版本,因为我来自Python世界,其中“显式优于隐式”。

Of course if type information on the parameter is needed the function version cannot be used. 当然,如果需要关于参数的类型信息,则不能使用function版本。

OTOH I like the argument made by Stringer so I will start to use function in simple lambdas. OTOH我喜欢Stringer的论点,所以我将开始在简单的lambda中使用function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM