0% found this document useful (0 votes)
34 views4 pages

CH 5

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views4 pages

CH 5

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Set Comprehensions

PROGRAMMING IN HASKELL
In mathematics, the comprehension notation can
be used to construct new sets from old sets.

{x2 | x  {1...5}}

The set {1,4,9,16,25} of all numbers x2 such


Chapter 5 - List Comprehensions that x is an element of the set {1…5}.

0 1

Lists Comprehensions Note:

In Haskell, a similar comprehension notation can z The expression x  [1..5] is called a generator,
be used to construct new lists from old lists. as it states how to generate values for x.

z Comprehensions can have multiple generators,


[x^2 | x  [1..5]] separated by commas. For example:

> [(x,y) | x  [1,2,3], y  [4,5]]


The list [1,4,9,16,25] of all numbers x^2
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
such that x is an element of the list [1..5].

2 3

z Changing the order of the generators changes z For example:


the order of the elements in the final list:
> [(x,y) | y  [4,5], x  [1,2,3]]

> [(x,y) | y  [4,5], x  [1,2,3]] [(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]

[(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]

z Multiple generators are like nested loops, with


later generators as more deeply nested loops x  [1,2,3] is the last generator, so
whose variables change value more frequently. the value of the x component of each
pair changes most frequently.
4 5

1
Dependant Generators Using a dependant generator we can define the
library function that concatenates a list of lists:
Later generators can depend on the variables that
are introduced by earlier generators. concat :: [[a]]  [a]
concat xss = [x | xs  xss, x  xs]

[(x,y) | x  [1..3], y  [x..3]]


For example:

The list [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)] > concat [[1,2,3],[4,5],[6]]


of all pairs of numbers (x,y) such that x,y are
elements of the list [1..3] and y  x. [1,2,3,4,5,6]
6 7

Guards Using a guard we can define a function that maps


a positive integer to its list of factors:
List comprehensions can use guards to restrict the
values produced by earlier generators. factors :: Int  [Int]
factors n =
[x | x  [1..n], n `mod` x == 0]
[x | x  [1..10], even x]

For example:

The list [2,4,6,8,10] of all numbers > factors 15


x such that x is an element of the
list [1..10] and x is even. [1,3,5,15]
8 9

A positive integer is prime if its only factors are 1 Using a guard we can now define a function that
and itself. Hence, using factors we can define a returns the list of all primes up to a given limit:
function that decides if a number is prime:

prime :: Int  Bool primes :: Int  [Int]


prime n = factors n == [1,n] primes n = [x | x  [2..n], prime x]

For example:
For example:
> prime 15
False
> primes 40
> prime 7
[2,3,5,7,11,13,17,19,23,29,31,37]
True
10 11

2
The Zip Function Using zip we can define a function returns the list
of all pairs of adjacent elements from a list:
A useful library function is zip, which maps two lists
to a list of pairs of their corresponding elements. pairs :: [a]  [(a,a)]
pairs xs = zip xs (tail xs)
zip :: [a]  [b]  [(a,b)]

For example:
For example:

> pairs [1,2,3,4]


> zip [’a’,’b’,’c’] [1,2,3,4]
[(1,2),(2,3),(3,4)]
[(’a’,1),(’b’,2),(’c’,3)]
12 13

Using pairs we can define a function that decides Using zip we can define a function that returns the
if the elements in a list are sorted: list of all positions of a value in a list:

sorted :: Ord a  [a]  Bool positions :: Eq a  a  [a]  [Int]


sorted xs = and [x  y | (x,y)  pairs xs]
positions x xs =
[i | (x’,i)  zip xs [0..], x == x’]
For example:

> sorted [1,2,3,4] For example:


True
> positions 0 [1,0,0,1,0,1,1,0]
> sorted [1,3,2,4]
False [1,2,4,7]
14 15

String Comprehensions Because strings are just special kinds of lists, any
polymorphic function that operates on lists can
also be applied to strings. For example:
A string is a sequence of characters enclosed in
double quotes. Internally, however, strings are
represented as lists of characters. > length "abcde"
5

"abc" :: String > take 3 "abcde"


"abc"

> zip "abc" [1,2,3,4]


Means [’a’, ’b’, ’c’] :: [Char].
[(’a’,1),(’b’,2),(’c’,3)]

16 17

3
Similarly, list comprehensions can also be used to Exercises
define functions on strings, such counting how
(1) A triple (x,y,z) of positive integers is called
many times a character occurs in a string:
pythagorean if x2 + y2 = z2. Using a list
comprehension, define a function
count :: Char  String  Int
count x xs = length [x’ | x’  xs, x == x’] pyths :: Int  [(Int,Int,Int)]

that maps an integer n to all such triples with


For example:
components in [1..n]. For example:

> count ’s’ "Mississippi" > pyths 5


4 [(3,4,5),(4,3,5)]
18 19

(2) A positive integer is perfect if it equals the sum (3) The scalar product of two lists of integers xs
of all of its factors, excluding the number itself. and ys of length n is give by the sum of the
Using a list comprehension, define a function products of the corresponding integers:

perfects :: Int  [Int] n-1

that returns the list of all perfect numbers up


 (xs * ys )
i i

to a given limit. For example: i=0

> perfects 500 Using a list comprehension, define a function


that returns the scalar product of two lists.
[6,28,496]
20 21

You might also like