Desculpe pelo título vago, mas parte desta questão é como esses dois estilos de sintaxe são chamados:
let foo1 x =
match x with
| 1 -> "one"
| _ -> "not one"
let foo2 = function
| 1 -> "one"
| _ -> "not one"
A outra parte é que diferença existe entre os dois e quando eu gostaria de usar um ou outro?
A vantagem da segunda sintaxe é que, quando usada em um lambda, pode ser um pouco mais concisa e legível.
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]
fonte
A versão da função é uma abreviação para a sintaxe de correspondência completa no caso especial em que a instrução de correspondência é a função inteira e a função tem apenas um único argumento (as tuplas contam como um). Se você quiser ter dois argumentos, precisará usar a sintaxe de correspondência completa *. Você pode ver isso nos tipos das duas funções a seguir.
//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 ??"
Como você pode ver, a versão de correspondência leva dois argumentos separados, enquanto a versão da função usa um único argumento tuplado. Eu uso a versão de função para a maioria das funções de argumento único, pois acho que a sintaxe da função parece mais limpa.
* Se você realmente quiser, pode obter a versão da função para ter o tipo de assinatura correto, mas parece muito feio na minha opinião - veja o exemplo abaixo.
//val function_match_equivalent : string -> string -> string let function_match_equivalent x y = (x, y) |> function | "A", _ -> "Hello A" | _, "B" -> "Hello B" | _ -> "Hello ??"
fonte
Eles fazem a mesma coisa no seu caso - a
function
palavra - chave atua como uma combinação dafun
palavra - chave (para produzir um lambda anônimo) seguida pelomatch
palavra chave.Então, tecnicamente, esses dois são iguais, com a adição de um
fun
:let foo1 = fun x -> match x with | 1 -> "one" | _ -> "not one" let foo2 = function | 1 -> "one" | _ -> "not one"
fonte
fun
é, é tecnicamente definido em termos defunction | _ -> ...
?fun x y -> ...
seriafun x -> fun y -> ...
, e entãofun x -> ...
seriafunction | x -> ...
. É por isso que você pode fazer correspondência de padrões emfun
- por exemplofun (x::xs) -> ...
.Apenas para completar, acabei de acessar a página 321 do Expert FSharp :
fonte
function permite apenas um argumento, mas permite a correspondência de padrões, enquanto fun é a maneira mais geral e flexível de definir uma função. Dê uma olhada aqui: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html
fonte
As duas sintaxes são equivalentes. A maioria dos programadores escolhe um ou outro e usa-o de forma consistente.
A primeira sintaxe permanece mais legível quando a função aceita vários argumentos antes de começar a trabalhar.
fonte
Esta é uma pergunta antiga, mas vou jogar meus $ 0,02.
Em geral eu gosto mais do
match
versão, já que venho do mundo Python, onde "explícito é melhor do que implícito".Claro, se a informação de tipo no parâmetro for necessária, o
function
versão não pode ser usada.OTOH Eu gosto do argumento feito por,
Stringer
então vou começar a usarfunction
em lambdas simples.fonte