The first function nexts shows that list is a monad. It uses the do notation and uses recursion to infinitely define the list.
The pairs function shows how the list monad works. The function is defined as follows:
pairs :: [a] -> [b] -> [(a,b)] pairs xs ys = do x <- xs y <- ys return (x,y)
It should read as follows:
for each x in xs for each y in ys create list of (x,y) concatenate lists to return a single list
The list monad binds each element of a list to the function, creating another list, and concatenates them back together. The return function creates a singleton list.
The partition function is implemented in two ways. The list comprehension for partition is [(x,y) | x <- xs, y <- ys, f x y], which is a short form ...