Pattern Matching

El Pattern Matching (coincidencia de patrones) es un mecanismo que compara una expresión con una estructura específica, la descompone en sus partes constituyentes y, si la comparación es exitosa, asigna variables a dichas partes.

Reemplaza las complejas estructuras condicionales if-else con bloques de código declarativos más limpios.

Está técnica es similar al uso del switch excepto que en lugar de comparar el valor de una variable o expresión, compara la estructura.

Pattern Matching en Haskell

Veamos para qué nos puede servir y cómo la podemos emplear.

¿Para qué se utiliza?

  • Revisar tipos y formas: Comprobar si un dato es un número, un texto, una lista o un objeto de cierto tipo.
  • Desarmar datos: Abrir objetos, tuplas o estructuras complejas para sacar sus valores internos sin usar funciones largas de extracción.
  • Reemplazar múltiples if / else: Escribir código más corto, ordenado y fácil de leer al evaluar opciones.

Ejemplos de Pattern Matching

El clásico programa del Factorial. Observemos el código en C.

factorial.c

#include <stdio.h>


int factorial(int n) {
    if (n == 0) {
        return 1; 
    } else {
        return n * factorial(n - 1); 
    }
}

int main() {
    int numero = 5;
    printf("El factorial de %d es %d\n", numero, factorial(numero));
    return 0;
}

En este código observamos el uso de sentencias if y la recursividad.

Con Haskell y el uso de ésta técnica (pattern matching) nos quedaría de esta manera:

factorial.hs

factorial :: Int -> Int
factorial 0 = 1
factorial num = num * factorial(num - 1)

main = print(factorial 5)

Ejecutamos:

$ runghc factorial.hs

Salida:

120

Ésta técnica se puede usar en números, cadenas, tuplas, listas y en tipos de datos predefinidos por nosotros mismos.

Tomemos en cuenta este código hecho en COBOL.

findesemana.cbl

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ESFINDESEMANA.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 DIA          PIC X(10).
       01 ES-FIN       PIC X(3).

       PROCEDURE DIVISION.
           DISPLAY "Ingrese un día: "
           ACCEPT DIA

           IF DIA = "Sábado" OR DIA = "Domingo"
               MOVE "Sí" TO ES-FIN
           ELSE
               MOVE "No" TO ES-FIN
           END-IF

           DISPLAY "¿Es fin de semana? " ES-FIN

           STOP RUN.

Ahora en Haskell.

findesemana.hs

esFinDeSemana dia = dia == "Sábado" || dia == "Domingo"

Entramos al REPL:

$ ghci

Cargamos el programa:

ghci> :l findesemana.hs

Probamos el código:

ghci> esFinDeSemana "Lunes"
False
ghci> esFinDeSemana "Domingo"
True
ghci> esFinDeSemana "Jueves"
False
ghci> esFinDeSemana "Sábado"
True
ghci> :q

En Haskell, el pattern matching nos ahorra muchas líneas de código. El uso de if-else anidados, el uso de switch complejos. Nos obliga a pensar de otra manera. Actualmente lenguajes como Java, C#, Kotlin, Scala, Rust y Go permiten la programación funcional y el uso de ésta técnica. Hemos dado una simple mirada a ésta poderosa técnica. Podríamos extender la explicación pero será en  otro momento.

Enlaces:

https://wiki.uqbar.org/wiki/articles/pattern-matching-en-haskell.html
https://www.campusmvp.es/recursos/post/Pattern-matching-en-lenguajes-de-programacion-funcionales.aspx?srsltid=AfmBOoo6DugPuMZ96ydPC1POIkfD07XM7Xba-kevV3MLOF_lezFKRvB_
https://www.haskell.org/tutorial/patterns.html

Comentarios

Entradas populares de este blog

Cabal

Lenguajes similares Haskell: Agda

Tipos de datos en Haskell