summaryrefslogtreecommitdiff
path: root/miralib/manual/13/2
blob: 2e86d88f9af4ebb14d4fcba8a212cfb5d10234a0 (plain)
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
_L_i_s_t_ _c_o_m_p_r_e_h_e_n_s_i_o_n_s

	[exp | qualifiers]

List of all `exp' such that `qualifiers'.  If  there  are  two  or  more
qualifiers they are separated by semicolons.  Each qualifier is either a
generator, of which the allowed forms are

	pattern-list <-  exp		(first form)

	pattern <- exp, exp ..		(second form)

or else a filter, which is a boolean expression restricting the range of
the   variables  introduced  by  preceding  generators.   The  variables
introduced on the left of each `<-' are local to the list comprehension.

Some examples

	sqs = [ n*n | n<-[1..] ]

	factors n = [ r | r<-[1..n div 2]; n mod r = 0 ]

	knights_moves [i,j] = [ [i+a,j+b] | a,b<-[-2..2]; a^2+b^2=5 ]

Notice that a list of variables on the lhs of a `<-'  is  shorthand  for
multiple generators, e.g. `i,j<-thing' expands to `i<-thing; j<-thing'.

The variables introduced by the generators come into scope from left  to
right,  so  later  generators  can  make  use of variables introduced by
earlier ones.  An example of this is shown by the  following  definition
of a function for generating all the permutations of a given list.

	perms [] = [[]]
	perms  x = [ a:p | a<-x; p<-perms(x--[a]) ]

The  second  form  of  generator  allows  the construction of lists from
arbitrary recurrence relations, thus
	x <- a, f x ..
causes x to assume in turn the values `a', `f a',  `f(f  a)',  etc.

An example of its use is in the following definition  of  the  fibonacci
series

	fibs = [ a | (a,b) <- (1,1), (b,a+b) .. ]

Another  example  is  given  by the following expression which lists the
powers of two

	[ n | n <- 1, 2*n .. ]

The  order  of  enumeration  of  a  list  comprehension  with   multiple
generators  is  like  that  of  nested  for-loops,  with  the  rightmost
generator  as  the  innermost  loop.   For  example  the  value  of  the
comprehension [ f x y | x<-[1..4]; y<-[1..4] ] is

	[ f 1 1, f 1 2, f 1 3, f 1 4, f 2 1, f 2 2, f 2 3, f 2 4,
	  f 3 1, f 3 2, f 3 3, f 3 4, f 4 1, f 4 2, f 4 3, f 4 4 ]

As a consequence of this order of enumeration of multiple generators, if
any  generator  other  than  the  first  (leftmost)  is  infinite,  some
combinations of values will never be reached  in  the  enumeration.   To
overcome  this  a  second,  _d_i_a_g_o_n_a_l_i_s_i_n_g, form of list comprehension is
provided (see separate manual section).

Note that list comprehensions do NOT remove duplicates from  the  result
list.   To  remove  duplicates  from a list, apply the standard function
`mkset'.