Las comprensiones de listas son una característica poderosa y expresiva de Haskell que permite construir listas de manera concisa y declarativa. Se inspiran en la notación matemática de conjuntos y proporcionan una forma elegante de generar y transformar listas.

Conceptos Clave

  1. Sintaxis Básica: La sintaxis de una comprensión de listas se parece a la notación de conjuntos en matemáticas.
  2. Generadores: Especifican cómo se generan los elementos de la lista.
  3. Filtros: Permiten incluir condiciones que los elementos deben cumplir.
  4. Expresiones: Definen cómo se transforman los elementos generados.

Sintaxis Básica

La forma general de una comprensión de listas es:

[ expresión | generador, filtro1, filtro2, ... ]
  • expresión: Define cómo se transforman los elementos.
  • generador: Especifica cómo se generan los elementos.
  • filtros: Condiciones que los elementos deben cumplir.

Ejemplo Básico

Generar una lista de los primeros 10 números naturales:

[ x | x <- [1..10] ]

Explicación

  • x <- [1..10] es el generador que toma cada x de la lista [1..10].
  • La expresión x simplemente devuelve cada x sin cambios.

Uso de Filtros

Podemos añadir filtros para incluir solo ciertos elementos. Por ejemplo, generar una lista de los primeros 10 números naturales que son pares:

[ x | x <- [1..10], even x ]

Explicación

  • x <- [1..10] genera los números del 1 al 10.
  • even x es un filtro que incluye solo los números pares.

Transformaciones

Podemos transformar los elementos generados. Por ejemplo, generar una lista de los cuadrados de los primeros 10 números naturales:

[ x^2 | x <- [1..10] ]

Explicación

  • x^2 es la expresión que transforma cada x en su cuadrado.

Múltiples Generadores

Podemos usar múltiples generadores para crear combinaciones de elementos. Por ejemplo, generar una lista de todas las combinaciones de los números del 1 al 3 con las letras 'a' y 'b':

[ (x, y) | x <- [1..3], y <- ['a', 'b'] ]

Explicación

  • (x, y) es la expresión que combina x y y en una tupla.
  • x <- [1..3] genera los números del 1 al 3.
  • y <- ['a', 'b'] genera las letras 'a' y 'b'.

Ejemplos Prácticos

Ejemplo 1: Números Primos

Generar una lista de números primos menores que 20:

primes = [ x | x <- [2..20], isPrime x ]
  where
    isPrime n = null [ y | y <- [2..n-1], n `mod` y == 0 ]

Explicación

  • x <- [2..20] genera los números del 2 al 20.
  • isPrime x es un filtro que incluye solo los números primos.
  • isPrime se define usando una comprensión de listas que verifica si n tiene divisores distintos de 1 y n.

Ejemplo 2: Tablas de Multiplicar

Generar una lista de las tablas de multiplicar del 1 al 10:

multiplicationTable = [ (x, y, x*y) | x <- [1..10], y <- [1..10] ]

Explicación

  • (x, y, x*y) es la expresión que combina x y y y calcula su producto.
  • x <- [1..10] y y <- [1..10] generan los números del 1 al 10.

Ejercicios Prácticos

Ejercicio 1: Números Impares

Generar una lista de los primeros 20 números impares.

impares = [ x | x <- [1..40], odd x ]

Ejercicio 2: Pares de Números

Generar una lista de todas las parejas de números del 1 al 5.

parejas = [ (x, y) | x <- [1..5], y <- [1..5] ]

Ejercicio 3: Filtrar y Transformar

Generar una lista de los cuadrados de los números del 1 al 20 que son divisibles por 3.

cuadradosDivisiblesPor3 = [ x^2 | x <- [1..20], x `mod` 3 == 0 ]

Soluciones

Solución al Ejercicio 1

impares = [ x | x <- [1..40], odd x ]

Solución al Ejercicio 2

parejas = [ (x, y) | x <- [1..5], y <- [1..5] ]

Solución al Ejercicio 3

cuadradosDivisiblesPor3 = [ x^2 | x <- [1..20], x `mod` 3 == 0 ]

Conclusión

Las comprensiones de listas en Haskell son una herramienta poderosa para generar y transformar listas de manera concisa y legible. Al dominar las comprensiones de listas, puedes escribir código más claro y expresivo, aprovechando al máximo las capacidades de Haskell para la programación funcional. En el próximo módulo, exploraremos el sistema de tipos de Haskell, comenzando con la inferencia de tipos.

© Copyright 2024. Todos los derechos reservados