Tal vez recuerden de matemática que se pueden definir conjuntos por extensión (por ejemplo {1,2,5,9}) o por comprensión ({X \ X Є Enteros ^ X > 3 ^ X < 15} ). La forma por extensión ya la vimos con en Haskell con las listas [1,2,5,9] y por comprensión podemos definirla mediante filtros y transformaciones (filter y map) sobre otra lista que sería el conjunto base.
Las listas por comprensión en Haskell son un azúcar sintáctico que nos permite armar listas a partir de los elementos de otra luego de aplicar filtros y transformaciones, o sea, permiten escribir de una forma simple y elegante expresiones que podrían ser más complejas utilizando las funciones que ya conocemos para este fin.
Veamos un ejemplo simple usando filter y map:
nombresDeAlumnosQueAprobaron = map nombre . filter aprobo
Esta función puede también escribirse con una lista por comprensión:
nombresDeAlumnosQueAprobaron alumnos = [nombre alumno | alumno <- alumnos, aprobo alumno]
Una diferencia que podemos notar entre ambas definiciones es la cantidad de parámetros a la izquierda del igual, en el segundo caso hay uno, mientras que en el primero no hay. ¿Por qué pasa eso?
Eso pasa porque
map nombre . filter aprobo
es una función ya que es la composición de dos funciones.
En cambio
[nombre alumno | alumno <- alumnos, aprobo alumno]
es una lista, esa es una diferencia importante y es un criterio que nos va a permitir saber cuándo nos conviene usar map y filter en lugar de listas por comprensión.
Otra cosa que agregan las listas por comprensión es la posibilidad de hacer pattern matching quedando aún más expresivo:
[nombre | (nombre, nota) <- alumnos, nota > 4]
Otro ejemplo si tengo una lista de remeras de la forma:
modelos = [("GoodIdeaBadIdea", "flex", 2, "negro"), ...]
A partir de esa lista podemos construir otra usando listas por comprensión y pattern matching:
[(nombre, color) | (nombre, _, cant, color) <- modelos, cant > 2]
Aquí se puede ver la verdadera potencia de las listas por comprensión vs. map y filter, la posibilidad de utilizar el pattern matching.
En resumen: