Explicación de la coincidencia de patrones vs interruptor


He estado tratando de explicar la diferencia entre las sentencias switch y pattern matching(F#) a un par de personas, pero realmente no he sido capaz de explicarlo bien..la mayoría de las veces me miran y dicen " así que, ¿por qué no usas si?.entonces..else".

¿Cómo se lo explicarías?

EDITAR! Gracias a todos por las grandes respuestas, realmente me gustaría poder marcar múltiples respuestas correctas.

Author: Nathan W, 2008-10-14

9 answers

Habiendo sido anteriormente una de "esas personas", no se si hay una manera sucinta de resumir por qué la coincidencia de patrones es tan sabrosa bondad. Es experiencial.

Cuando acababa de echar un vistazo a pattern-matching y pensé que era una sentencia switch glorificada, creo que no tenía experiencia programando con tipos de datos algebraicos (tuplas y uniones discriminadas) y no vi que pattern matching era tanto una construcción de control como una construcción de enlace. Ahora que he estado programando con F#, finalmente "lo entiendo". La frescura de la coincidencia de patrones se debe a una confluencia de características que se encuentran en los lenguajes de programación funcionales, por lo que no es trivial para el observador externo apreciarlo.

Traté de resumir un aspecto de por qué la coincidencia de patrones es útil en la segunda de una breve serie de blogs de dos partes sobre el lenguaje y el diseño de API; echa un vistazo a parte uno y parte dos.

 35
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-14 04:15:07

Los patrones le dan un pequeño lenguaje para describir la estructura de los valores que desea que coincidan. La estructura puede ser arbitrariamente profunda y puede enlazar variables a partes del valor estructurado.

Esto le permite escribir las cosas de manera extremadamente sucinta. Puede ilustrar esto con un pequeño ejemplo, como una función derivada para un tipo simple de expresiones matemáticas:

type expr =
    | Int of int
    | Var of string
    | Add of expr * expr
    | Mul of expr * expr;;

let rec d(f, x) =
    match f with
    | Var y when x=y -> Int 1
    | Int _ | Var _ -> Int 0
    | Add(f, g) -> Add(d(f, x), d(g, x))
    | Mul(f, g) -> Add(Mul(f, d(g, x)), Mul(g, d(f, x)));;

Además, debido a que la coincidencia de patrones es una construcción estática para tipos estáticos, el compilador puede (i) verificar que cubrió todos los casos (ii) detectar ramas redundantes que nunca pueden coincidir con ningún valor (iii) proporcionar una implementación muy eficiente (con saltos, etc.).

 29
Author: Bruno De Fraine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-06 07:48:07

Extracto de este artículo del blog :

La coincidencia de patrones tiene varias ventajas sobre las instrucciones switch y el envío de métodos:

  • Las coincidencias de patrones pueden actuar sobre ints, flotadores, cuerdas y otros tipos como así como objetos.
  • Las coincidencias de patrones pueden actuar sobre varios diferentes valores simultáneamente: coincidencia de patrones paralelos. Método el envío y el interruptor están limitados a un solo valor, por ejemplo, "esto".
  • Los patrones pueden anidarse, permitiendo despacho sobre árboles de arbitrario profundidad. El envío del método y el interruptor son limitados al caso no anidado.
  • Los patrones Or permiten que los sub-patrones sean compartir. Método el envío solo permite compartir cuando los métodos son de clases que comparten una base clase. De lo contrario, debe manualmente factor fuera de lo común en un función separada (dándole un nombre) y luego insertar llamadas manualmente de todos los lugares apropiados a su función innecesaria.
  • La coincidencia de patrones proporciona redundancia control de las capturas error.
  • Patrón anidado y / o paralelo los partidos están optimizados para usted por el Compilador F#. El equivalente de OO debe ser escrito a mano y constantemente reoptimizado a mano durante desarrollo, que es prohibitivamente tedioso y propenso a errores el código OO de calidad de producción tiende a ser extremadamente lento en comparación.
  • Los patrones activos le permiten inyectar semántica de despacho personalizado.
 13
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-05 11:15:03

De la parte superior de mi cabeza:

  1. El compilador puede saber si no has cubierto todas las posibilidades en tus coincidencias
  2. Puede usar una coincidencia como una asignación
  3. Si tienes un sindicato discriminado, cada partido puede tener un'tipo' diferente
 7
Author: Benjol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-14 06:44:13

Las tuplas tienen "," y las variantes tienen args Ctor .. estos son constructores, crean cosas.

Los patrones son destructores, los destrozan.

Son conceptos duales.

Para decirlo con más fuerza: la noción de una tupla o variante no puede ser descrita simplemente por su constructor: el destructor es requerido o el valor que usted hizo es inútil. Son estas descripciones duales las que definen un valor.

Generalmente pensamos en los constructores como datos, y los destructores como control de flujo. Los destructores de variantes son ramas alternas (una de muchas), los destructores de tuplas son hilos paralelos (todos de muchas).

El paralelismo es evidente en operaciones como

(f * g) . (h * k) = (f . h * g . k) 

Si piensa en el control que fluye a través de una función, las tuplas proporcionan una forma de dividir un cálculo en hilos paralelos de control.

Visto de esta manera, las expresiones son formas de componer tuplas y variantes para hacer estructuras de datos complicadas (piense en un AST).

Y patrón los partidos son formas de componer los destructores (de nuevo, piensa en un AST).

 5
Author: Yttrill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-05 15:56:43

El interruptor son las dos ruedas delanteras.

Pattern-matching es todo el coche.

 4
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-14 22:23:31

Las coincidencias de patrones en OCaml, además de ser más expresivas como se mencionó en varias formas que se han descrito anteriormente, también dan algunas garantías estáticas muy importantes. El compilador le demostrará que el análisis de casos encarnado por su declaración pattern-match es:

  • exhaustivo (no se omiten casos)
  • no redundante (no hay casos que nunca puedan ser afectados porque se anticipan a un caso anterior)
  • sonido (no hay patrones que son imposibles dada la tipo de datos en cuestión)

Esto es muy importante. Es útil cuando estás escribiendo el programa por primera vez, y enormemente útil cuando tu programa está evolucionando. Si se usan correctamente, las sentencias match facilitan el cambio de tipos en el código de forma fiable, ya que el sistema de tipos le apunta a las sentencias match rotas, que son un indicador decente de dónde tiene el código que debe corregirse.

 3
Author: zrr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-08 14:54:02

Las instrucciones If-Else (o switch) tratan de elegir diferentes formas de procesar un valor (input) dependiendo de las propiedades del valor en cuestión.

Pattern matching se trata de definir cómo procesar un valor dada su estructura , (también tenga en cuenta que las coincidencias de patrón de caso único tienen sentido).

Por lo tanto, la coincidencia de patrones se trata más de deconstruir valores que de hacer elecciones, esto los convierte en un mecanismo muy conveniente para definir funciones (recursivas) en inductivas estructuras (tipos de unión recursiva), lo que explica por qué se utilizan tan abundantemente en lenguajes como Ocaml, etc.

PD: Es posible que conozca los "patrones" pattern-match y If-Else por su uso ad-hoc en matemáticas;

"si x tiene la propiedad A entonces y else z" (If-Else)

" algún término en p1..pn dónde .... es la descomposición principal de x.."(coincidencia de patrón (caso único))

 0
Author: D.F.F,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-11 11:16:16

¿Quizás podría hacer una analogía con las cadenas y las expresiones regulares? Describe lo que estás buscando, y deja que el compilador averigüe cómo por sí mismo. Hace que su código sea mucho más simple y claro.

Como un aparte: Me parece que lo más útil acerca de la coincidencia de patrones es que fomenta los buenos hábitos. Me ocupo de los casos de esquina primero, y es fácil comprobar que he cubierto todos los casos.

 -1
Author: Pitarou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-14 03:41:19