File: part6.lhs

package info (click to toggle)
haskell98-tutorial 200006-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 624 kB
  • ctags: 11
  • sloc: haskell: 2,125; makefile: 80; sh: 13
file content (80 lines) | stat: -rw-r--r-- 2,349 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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