12

Por lo tanto, soy totalmente nuevo en OCaml y me muevo con bastante lentitud para implementar mis primeras funciones. Una cosa que no puedo entender es cuándo utilizar las capacidades de patrones a juego comoOCaml: coincidencia de patrones frente a sentencias If/else

let foo = 
[] -> true 
| _ -> false;; 

vs utilizando la estructura más si como

let foo a = 
if a = [] then true else false;; 

Cuándo debo utilizar cada uno?

+1

La respuesta aceptada a continuación parece buena en la mayoría de los casos. Sin embargo, al igual que en la mayoría (¿todos?) De los lenguajes de programación, rara vez es una buena idea decir algo similar a 'if condition then true else false'; en su lugar, simplemente puede usar 'condición'. En este caso, puede decir 'let foo a = (a = [])' y evitar ambas coincidencias de patrones y if. –

Respuesta

15

No creo que haya una respuesta clara a esa pregunta. En primer lugar, el caso evidente de coincidencia de patrones es cuando se necesita destructing, por ejemplo:

let rec sum = function 
    | [] -> 0 
    | head :: tail -> head + sum tail;; 

Otro caso es obvia cuando se está definiendo una función recursiva, coincidencia de patrones que la condición de borde más claro, por ejemplo:

let rec factorial = function 
    | 0 -> 1 
    | n -> n * factorial(n - 1);; 

en lugar de:

let rec factorial = function n -> 
    if n = 0 then 
    1 
    else 
    n * factorial(n-1);; 

Esto puede no ser un gran ejemplo, sólo tiene que utilizar su imaginación para idear condiciones de borde más complejas! ;-)

En términos de (digamos) C ¿Te gusta lenguajes regulares, podría decir que se debe utilizar en lugar de coincidencia de patrones switch/case y if en lugar del operador ternario. Para todo lo demás, es una especie de zona gris, pero en general se prefiere la coincidencia de patrones en la familia de idiomas ML.

+0

+1. Aumentaría esto con una regla general más. Si está haciendo una coincidencia de patrones contra 'true' y' false', considere un 'si'. Si su 'if' usa una función para expresar una coincidencia de patrón clara, considere' match'. Además 'match' puede evitar llamadas a funciones, a diferencia de muchas expresiones' if'. –

+0

¡Ese es un buen punto! –

2

Hasta donde yo sé, la diferencia significativa es que la expresión en los guardias en el enunciado del partido es pattern lo que significa que puedes hacer cosas que te permiten separar la forma (destruir) la expresión coincidente, como Nicolas mostró en su respuesta. La otra implicación de esto es que el código de la siguiente manera:

let s = 1 in 
    let x = 2 in 
    match s with 
    x -> Printf.printf "x does not equal s!!\n" x 
    | _ -> Printf.printf "x = %d\n" x; 

no hará lo que usted espera. Esto se debe a que x en la declaración de coincidencia no hace referencia al x en la instrucción let anterior, sino que es un nombre del patrón. En casos como estos, necesitaría usar las declaraciones if.

0

La coincidencia de patrones permite la deconstrucción de tipos de datos compuestos y, en general, la capacidad de unir patrones dentro de una estructura de datos dada, en lugar de utilizar condicionales como la estructura if .. then. La coincidencia de patrones también se puede usar para casos de igualdad booleanos utilizando la construcción de tipo | x when (r == n). También debo agregar que la coincidencia de patrones es mucho más eficiente que si ... entonces ... construye, ¡así que úsala libremente!

+0

FWIW, no creo que 'combine x con 3 -> f x | _ -> g x' va a ser más eficiente que 'si x = 3 luego f x else g x'. Personalmente me concentraría en la claridad del código. –

+0

En ese caso, estaría de acuerdo. Pero considere el caso, 'partido x con | 0 -> 1 | 1 -> 2 | 2 -> 3 | _ -> x + 1' vs 'si x = 0 luego 1 else si x = 1 luego 2 else si x = 2 luego 3 else x + 1'. Si tuviera que comparar estas funciones, la coincidencia de patrones sería significativamente más eficiente. A medida que los casos aumentan (especialmente cuando se acelera con la recursión), las diferencias de rendimiento pueden aumentar en órdenes de magnitud. –

Cuestiones relacionadas