很抱歉这个模糊的标题,但这个问题的一部分是这两种语法样式的调用:
let foo1 x =
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
Run Code Online (Sandbox Code Playgroud)
另一部分是两者之间的区别,当我想要使用其中一个时?
Str*_*ger 72
第二种语法的专业版是,当在lambda中使用时,它可能更简洁和可读.
List.map (fun x -> match x with | 1 -> "one" | _ -> "not one") [0;1;2;3;1]
Run Code Online (Sandbox Code Playgroud)
VS
List.map (function 1 -> "one" | _ -> "not one") [0;1;2;3;1]
Run Code Online (Sandbox Code Playgroud)
Jos*_*hua 20
在特殊情况下,函数版本是完全匹配语法的简写,其中match语句是整个函数,函数只有一个参数(元组计数为1).如果你想有两个参数,那么你需要使用完全匹配语法*.您可以在以下两个函数的类型中看到这一点.
//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 ??"
Run Code Online (Sandbox Code Playgroud)
如您所见,匹配版本采用两个单独的参数,而函数版本采用单个tupled参数.我对大多数单个参数函数使用函数版本,因为我发现函数语法看起来更干净.
*如果你真的想要你可以获得功能版本以获得正确的类型签名但在我看来它看起来很丑 - 见下面的例子.
//val function_match_equivalent : string -> string -> string
let function_match_equivalent x y = (x, y) |> function
| "A", _ -> "Hello A"
| _, "B" -> "Hello B"
| _ -> "Hello ??"
Run Code Online (Sandbox Code Playgroud)
Tim*_*son 12
它们在您的情况下也做同样的事情 - function
关键字的作用类似于fun
关键字(生成匿名lambda)后跟match
关键字的组合.
所以在技术上这两个是相同的,增加了一个fun
:
let foo1 = fun x ->
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
Run Code Online (Sandbox Code Playgroud)
为了完整起见,我得到了Expert FSharp的第321页:
"注意,清单12-2使用表达式形式
function pattern-rules -> expression
.这相当于(fun x -> match x with pattern-rules -> expression)
并且特别方便,可以定义直接在有区别的联合上工作的函数."