CSc 372 - Comparative Programming Languages
13 : Haskell -- List Comprehension

Christian Collberg

Department of Computer Science

University of Arizona

1 List Comprehensions

2 Generator Qualifiers


\begin{gprogram}
\mbox{[n \vert n<-[1..5]]} $\Rightarrow$\ [1,2,3,4,5] \\
\\
\...
...ox{[(n,n*n) \vert n<-[1..3]]} $\Rightarrow$\ [(1,1),(2,4),(3,9)]
\end{gprogram}

3 Filter Qualifiers


\begin{gprogram}
\mbox{[n*n \vert n<-[1..9],even n]} $\Rightarrow$\ [4,16,36,64]...
...ox{[(n,n*n) \vert n<-[1..3],n<n*n]} $\Rightarrow$\ [(2,4),(3,9)]
\end{gprogram}

4 Local Definitions


\begin{gprogram}
\xx \mbox{[n*n \vert n = 2]} $\Rightarrow$\ [4]
\end{gprogram}

5 Qualifiers

Pascal:
\begin{gprogram}
for i := 1 to 9 do \\
\x for j := 1 to 3 do \\
\xx print (i, j)
\end{gprogram}

Haskell:
\begin{gprogram}[(i,j) \vert i<-[1..9], j<-[1..3]] $\Rightarrow$\ \\
\xx [\x (1...
...(2,1),(2,2),(2,3),\\
\xxxx $\cdots$\ \\
\xxx (9,1),(9,2),(9,3)]
\end{gprogram}

6 Qualifiers...

Pascal:
\begin{gprogram}
for i := 1 to 3 do \\
\x for j := i to 4 do \\
\xx print (i, j)
\end{gprogram}

Haskell:
\begin{gprogram}[(i,j) \vert i<-[1..3], j<-[i..4]] $\Rightarrow$\ \\
\xx [\x (1...
...x{[n*n \vert n<-[1..10], even n]} $\Rightarrow$\ [4,16,36,64,100]
\end{gprogram}

7 Example

In English:

``Generate a list of elements of the form 2*x, where the x:s are the positive elements from the list xs.

In Haskell:
\begin{gprogram}
doublePos :: [Int] -> [Int] \\
doublePos xs = [2*x \vert x<-xs, x>0] \\
\\
\redtt{> doublePos [-1,-2,1,2,3]} \\
\x [2,4,6]
\end{gprogram}

8 Example

Example:
\begin{gprogram}
\redtt{> spaces 10} \\
\x ''\ \ \ \ \ \ \ \ \ \ ''
\end{gprogram}

Haskell:
\begin{gprogram}
spaces :: Int -> String \\
spaces n = [' ' \vert i <- [1..n]]
\end{gprogram}

9 Example

Examples:
\begin{gprogram}
factors 5 $\Rightarrow$\ [] \\
factors 100 $\Rightarrow$\ [2,4,5,10,20,25,50]
\end{gprogram}

In Haskell:
\begin{gprogram}
factors :: Int -> [Int] \\
factors n = [i \vert i<-[2..n-1], n \lq mod\lq  i == 0]
\end{gprogram}

10 Example

Pythagorean Triads:


\begin{gprogram}
triads n = [(x,y,z)\vert \\
\x x<-[1..n], y<-[1..n], z<-[1..n]...
... == z\verb+^+2] \\
\\
triads 5 $\Rightarrow$\ [(3,4,5),(4,3,5)]
\end{gprogram}

11 Example...


\begin{gprogram}
triads' n = [(x,y,z)\vert \\
\x x<-[1..n], y<-[x..n], z<-[y..n...
...z\verb+^+2] \\
\\
triads' 11 $\Rightarrow$\ [(3,4,5), (6,8,10)]
\end{gprogram}

12 Example - Making Change

Defining available (UK) coins:
\begin{gprogram}
type Coin = Int \\
coins :: [Coin] \\
coins = reverse (sort [1,2,5,10,20,50,100])
\end{gprogram}

Example:
\begin{gprogram}
\redtt{> change 23} \\
\x [20,2,1] \\
\redtt{> coins} \\
\x ...
...> all\_change 4} \\
\x [[2,2],[2,1,1],[1,2,1],[1,1,2],[1,1,1,1]]
\end{gprogram}

13 Example - Making Change...


\begin{gprogram}
change amount = head (all\_change amount)
\end{gprogram}


\begin{gprogram}
all\_change :: Int -> [[Coin]] \\
all\_change 0 = [[]] \\
all...
...
\xx c<-coins, amount>=c, \\
\xx cs<-all\_change (amount - c) ]
\end{gprogram}

14 Example - Making Change...

15 Example - Making Change...


\begin{gprogram}
all\_change :: Int -> [[Coin]] \\
all\_change 0 = [[]] \\
all...
...
\xx c<-coins, amount>=c, \\
\xx cs<-all\_change (amount - c) ]
\end{gprogram}

16 Summary

17 Homework


  1. \begin{gprogram}[n*n \vert n<-[1..10],even n]
\end{gprogram}

  2. \begin{gprogram}[7 \vert n<-[1..4]]
\end{gprogram}

  3. \begin{gprogram}[ (x,y) \vert x<-[1..3], y<-[4..7]]
\end{gprogram}

  4. \begin{gprogram}[ (m,n) \vert m<-[1..3], n<-[1..m]]
\end{gprogram}

  5. \begin{gprogram}[j \vert i<-[1,-1,2,-2], i>0, j<-[1..i]]
\end{gprogram}

  6. \begin{gprogram}[a+b \vert (a,b)<-[(1,2),(3,4),(5,6)]]
\end{gprogram}

18 Homework

Template:
\begin{gprogram}
neglist :: [Int] -> Int \\
neglist n = $\cdots$
\end{gprogram}

Examples:
\begin{gprogram}
\redtt{> neglist [1,2,3,4,5]} \\
\x 0 \\
\redtt{> neglist [1,-3,-4,3,4,-5]} \\
\x 3
\end{gprogram}

19 Homework

Template:
\begin{gprogram}
gensquares :: Int -> Int -> [Int] \\
gensquares low high = [ $\cdots$\ \vert $\cdots$\ ]
\end{gprogram}

Examples:
\begin{gprogram}
\redtt{> gensquares 2 5} \\
\x [4, 16] \\
\redtt{> gensquares 3 10} \\
\x [16, 36, 64, 100]
\end{gprogram}



Christian S. Collberg
2005-09-19