List comprehensions allow defining of many functions on lists in a simple way.

## Basic Concepts

In mathematics, the comprehension notation can be used to construct new sets from existing sets.

For example, the comprehension `{x² | x ∈ {1..5}}` produces the set `{1, 4, 9, 16, 25}`.

The symbol `|` is read as such that, `<-` is read as is drawn from, and the expression `x <- [1..5]` is called a generator.

The order of generators produces the same set of pairs, but arranged in different order.

Multiple generators are like nested loops, with later generators as more deeply nested loops, whose values change more frequently.

Later generator can depend upon values of earlier generators.

A more useful example of using list comprehensions.

Wildcard pattern `_` can be used to discard a value from a list.

## Guards

A guard can be used to filter values produced by earlier generators.

If a guard is `True`, then the current value is retained, if it is `False` then it is discarded.

For example, the comprehension `[x | x <- [1..10], even x]` produces the list `[2,4,6,8,10]`.

A function to find all the factors of an integer.

Combining both functions to find if a integer is prime.

Creating a list of primes by reusing the previous function.

Finds values by a key from a list of pairs.

## Zip Function

The library function zip produces a new list by pairing successive elements from two existing lists until either or both lists are exhausted.

Notice that zip stops when one of the lists end is reached.

Zip function can be useful with list comprehensions.

Checks if a list of elements is sorted.

Finds all the positions of a provided value in a list.

## String Comprehensions

In Haskell a string is represented as a list of characters. Which allows to use any polymorphic list functions on a string.

Over and out.