Gentle Introduction to Haskell 98, Online Supplement 
Part 5
Covers Sections 2.5.1, 2.5.2

> module Part6() where

Section: 2.5.1  List Comprehensions and Arithmetic Sequences

Warning: brackets in Haskell are used in three different sorts
of expressions: lists, as in [a,b,c], sequences (distinguished by
the ..), as in [1..2], and list comprehensions (distinguished by the
bar: |), as in [x+1 | x <- xs, x > 1].

Before list comprehensions, consider sequences:

> e1 :: [Int]
> e1 = [1..10]   -- Step is 1
> e2 :: [Int]
> e2 = [1,3..10] -- Step is 3 - 1
> e3 :: [Int]
> e3 = [1,-1.. -10]  -- The space before - is necessary!
> e4 :: [Char]
> e4 = ['a'..'z']   -- This works on chars too

We'll avoid infinite sequences like [1..] for now.  If you print one,
use C-c i to interrupt the Haskell program.

List comprehensions are very similar to nested loops.  They return a
list of values generated by the expression inside the loop.  The filter
expressions are similar to conditionals in the loop.

This function does nothing at all!  It just scans through a list and
copies it into a new one.

> doNothing :: [a] -> [a]
> doNothing l = [x | x <- l]

Adding a filter to the previous function allows only selected elements to
be generated.  This is similar to what is done in quicksort.

> positives :: [Int] -> [Int]
> positives l = [x | x <- l, x > 0]

> e5 = positives [2,-4,5,6,-5,3]

Now the full quicksort function.

> quicksort :: [Char] -> [Char]  -- Use Char just to be different!
> quicksort [] = []
> quicksort (x:xs) = quicksort [y | y <- xs, y <= x] ++
>                    [x] ++
>                    quicksort [y | y <- xs, y > x]

> e6 = quicksort "Why use Haskell?"

Now for some nested loops.  Each generator, <-, adds another level of
nesting to the loop.  The variable introduced by each generator
can be used in each following generator; all variables can be used in the
generated expression:

> e7 :: [(Int,Int)]
> e7 = [(x,y) | x <- [1..5], y <- [x..5]]

Now add some guards: (the /= function is `not equal')

> e8 :: [(Int,Int)]
> e8 = [(x,y) | x <- [1..7], x /= 5, y <- [x..8] , x*y /= 12]

This is the same as the loop: (going to a psuedo Algol notation)
for x := 1 to 7 do
 if x <> 5 then
  for y := x to 8 do
   if x*y <> 12
    generate (x,y)

Section: 2.5.2  Strings

> e9 = "hello" ++ " world"

Continued in part7.lhs
