2009-12-03 13 views
65

Lo siento por el título vago, pero parte de esta pregunta es lo que estos dos estilos de sintaxis se llaman:F # concordancia explícito vs sintaxis de la función

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

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

La otra parte es la que no existe diferencia entre los dos, y cuando Me gustaría usar uno u otro?

Respuesta

40

La versión de concordancia se llama una "expresión de coincidencia de patrones". La versión de la función se denomina "función de coincidencia de patrones". Se encuentra en la sección 6.6.4 de la spec.

El uso de uno sobre el otro es una cuestión de estilo. Prefiero solo usar la versión de función cuando necesito definir una función que es solo una declaración de coincidencia.

10

Hacen lo mismo en su caso: la palabra clave function actúa como una combinación de la palabra clave fun (para producir una lambda anónima) seguida de la palabra clave match.

Así que técnicamente estos dos son lo mismo, con la adición de un fun:

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

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

¿No es realmente al revés? Es decir, 'diversión' se define técnicamente en términos de' función | _ -> ... '? –

+1

Para ser específico, 'fun xy -> ...' sería 'diversión x -> diversión y -> ...', y luego 'diversión x -> ...' sería 'función | x -> ... '. Es por eso que puedes hacer coincidencias de patrones en 'divertido' - p. Ej. 'fun (x :: xs) -> ...'. –

2

Los dos sintaxis son equivalentes. La mayoría de los programadores eligen uno u otro y luego lo usan de manera consistente.

La primera sintaxis sigue siendo más legible cuando la función acepta varios argumentos antes de comenzar a trabajar.

59

El pro para la segunda sintaxis es que cuando se utiliza en una lambda, que podría ser un poco más concisa y fácil de leer.

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] 
14

La versión de función es una breve parte de la sintaxis partido completo en el caso especial en que la declaración partido es la función entera y la función sólo tiene un único argumento (tuplas cuentan como uno). Si desea tener dos argumentos, debe usar la sintaxis de coincidencia completa *. Puedes ver esto en los tipos de las siguientes dos funciones.

//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 puede ver, la versión de coincidencia toma dos argumentos separados, mientras que la versión de la función toma un único argumento acumulado. Utilizo la versión de la función para la mayoría de las funciones de un solo argumento, ya que encuentro que la sintaxis de la función parece más limpia.

* Si realmente quería que usted puede conseguir la versión de función para tener el tipo de firma correcta, pero se ve bastante feo en mi opinión - véase el ejemplo a continuación.

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

sólo por el bien completo, acabo de recibir a la página 321 de Expert FSharp:.

"Nota El listado 12-2 utiliza la forma de expresión function pattern-rules -> expression Esto es equivalente a (fun x -> match x with pattern-rules -> expression) y es especialmente conveniente, ya una forma de definir las funciones que trabajan directamente sobre los sindicatos discriminados."

4

función sólo permite un argumento, pero permite la coincidencia de patrones, mientras que diversión es la forma más general y flexible para definir una función Echa un vistazo aquí:. http://caml.inria.fr/pub/docs/manual-ocaml/expr.html

+0

¿por qué dices solo 1 argumento en lugar de solo el último argumento? es posible tener más de 1 argumento y usar "función". ¿Es esta una interpretación de función de orden superior? – symbiont

0

Ésta es una vieja pregunta, pero voy a tirar mi $ 0,02.

En general me gusta más la versión match ya que vengo del mundo de Python donde "explícito es mejor que implícito."

Por supuesto, si se necesita información del tipo sobre el parámetro, no se puede usar la versión function.

OTOH Me gusta el argumento hecho por Stringer así que comenzaré a usar function en lambdas simples.