CSc 372 - Comparative Programming Languages
8 : Haskell -- Function Examples

Christian Collberg

Department of Computer Science

University of Arizona


Functions over Lists


1 Breaking Lists -- ctake

Examples:
\begin{gprogram}
ctake 3 ['a','b','c','d','e'] $\Rightarrow$\ ['a','b','c'] \\
ctake 3 ['a','b'] $\Rightarrow$\ ['a','b']
\end{gprogram}
Haskell:
\begin{gprogram}
ctake :: Int -> [Char] -> [Char] \\
ctake 0 \_ \xxxxxxx = [\ ]...
... \xxxxxxx = [\ ] \\
ctake (n+1) (x:xs) \xxxxxxx = x : ctake n xs
\end{gprogram}

2 Don't Get Confused!

3 Breaking Lists -- drop

Examples:
\begin{gprogram}
drop 3 ['a','b','c','d','e'] $\Rightarrow$\ ['d','e'] \\
drop ...
...Rightarrow$\ [\ ] \\
drop 3 [1,2,3,4,5] $\Rightarrow$\ [4,5] \\
\end{gprogram}
Haskell:
\begin{gprogram}
drop :: Int -> [a] -> [a] \\
drop 0 xs \xxxxxxx = xs \\
drop \_ [\ ] \xxxxxxx = [\ ] \\
drop (n+1) (x:xs) \xxxxxxx = drop n xs
\end{gprogram}

4 Don't Get Confused (take 2)!

5 List Element Selection

Examples:
\begin{gprogram}
\mbox{[2,5,8,3,9,5,7]} !!3 \xxxxxxxx $\Rightarrow$\ 3 \\
\mbox...
... \\
\mbox{[[1],[2,3],[4]]} !!1!!0 \xxxxxxxx $\Rightarrow$\ 2 \\
\end{gprogram}


\begin{gprogram}
elmt :: [Int] -> Int -> Int\\
elmt (x:\_) 0 \xxxxxx = x\\
elmt (\_:xs) (n+1) \xxxxxx = elmt xs n
\end{gprogram}

6 Don't Get Confused (take 3)!


\begin{gprogram}
infixl 9 !! \\
\\
(!!) :: [a] -> Int -> a \\
(x:\_) !! 0 \xxxxxx = x \\
(\_:xs) !! (n+1) \xxxxxx = xs !! n
\end{gprogram}

7 The zip Function

Examples:
\begin{gprogram}
zip [1,2] ['a','b'] $\Rightarrow$\ [(1,'a'),(2,'b')] \\
zip [1,2,3] ['a','b'] $\Rightarrow$\ [(1,'a'),(2,'b')]
\end{gprogram}
Haskell:
\begin{gprogram}
zip :: [a] -> [b] -> [(a,b)] \\
zip (x:xs) (y:ys) = (x,y) : zip xs ys \\
zip \_ \_ = [\ ]
\end{gprogram}

8 The remdups Function

9 The remdups Function...

Algorithm in English:

Case 1:
Let the first two elements of the list be x and y. Let x==y. Example: L==[1,1,2,3], x==y==1. Discard x. Recursively remove duplicates from the remaining list L=[1,2,3].
Case 2:
The first two elements of the list (x,y) are different (x/=y). Example: L==[1,2,2,3], x==1, y==2. Append x onto the result of removing duplicates from the list L'=[2,2,3] from which x has been removed.
Case 3:
The list has 0 or 1 element. Return it.

10 The remdups Function...

Simulation:
\begin{gprogram}
remdups [1,2,2] $\Rightarrow$\ \\
\x 1:(remdups 2:[2]) $\equiv...
...Rightarrow$\ \xxxxxx $\Leftarrow$
case 3,xs=[2] \\
\xxx [1,2]
\end{gprogram}

11 The remdups Function...

Algorithm in Haskell:
\begin{gprogram}
remdups :: [Int] -> [Int] \\
remdups x:y:xs = \\
\x if x == y...
...arrow$\ case 2 \\
remdups xs = xs \xxxxxxxx $\Leftarrow$\ case 3
\end{gprogram}

case 1:
First two elements identical.
case 2:
First two elements different.
case 3:
Less than 2 elements left.

12 Haskell Guards

13 Haskell Guards...

fact with guards:
\begin{gprogram}
fact :: Int -> Int \\
fact n \\
\x \vert n==0 \xxxx = 1 \\
\x \vert otherwise \xxxx = n * fact (n-1)
\end{gprogram}

remdups with guards:
\begin{gprogram}
remdups :: Eq [a] => [a] -> [a] \\
remdups (x:y:xs) \\
\x \ve...
...\
\x \vert x /= y \xxxx = x : remdups (y:xs) \\
remdups xs = xs
\end{gprogram}

14 Don't Get Confused (take 4)!

15 The append Function

16 The append Function...

``Algorithm'' for append xs ys:

  1. Take xs apart and use cons to put the elements together to make a new list.
  2. Again use cons to make ys the tail of this new list.

17 The append Function...

Simulation:
\begin{gprogram}
append [1,2,3] [4,5] $\Rightarrow$\ \\
\x 1: (append [2,3] [4,...
...htarrow$\ \\
\xx 1: [2,3,4,5] $\Rightarrow$\ \\
\x [1,2,3,4,5]
\end{gprogram}

18 The append Function...

19 The append Function...

Algorithm in Haskell:
\begin{gprogram}
append :: [a] -> [a] -> [a] \\
append [\ ] xs = xs \\
append (x:xs) ys = x : append xs ys
\end{gprogram}

++ as append:


\begin{gprogram}
infixr 5 ++ \\
(++) :: [a] -> [a] -> [a] \\
\mbox{[\ ]}++xs = xs \\
(x:xs) \verb!++! ys = x : (xs \verb!++! ys)
\end{gprogram}


Local Definitions


20 The where Clause

21 The where Clause...

22 The where Clause...


\begin{gprogram}
deriv f x = \\
\x (f(x+dx) - f x)/dx \\
\xxx where dx = 0.0001 \\
\\
sqrt x = newton f x \\
\xxx where f y = y\verb+^+2 - x
\end{gprogram}

23 The where Clause...


\begin{gprogram}
g :: Int -> Int \\
g n \xx \vert \xx (n \lq mod\lq  3) == x \xxxxxx ...
...here \xx x = 0 \\
\xx \xxxx \xx y = 1 \\
\xx \xxxx \xx z = 2
\end{gprogram}

24 The let Clause

25 The let Clause...


\begin{gprogram}
f :: [Int] -> [Int] \\
f [\ ] = [\ ] \\
f xs = \\
\x let \\ ...
... 1 \\
\xx (y:ys) = xs \\
\x in \\
\xx (square y + one) : f ys
\end{gprogram}

26 The let Clause...


\begin{gprogram}
f [1,2] $\Rightarrow$\ \\
\x (square 1 + one) : f [2] $\Righta...
... : []) $\Rightarrow$\ \\
\xx 2 : [5] $\Rightarrow$\ \\
\x [2,5]
\end{gprogram}


Rational Arithmetic Package


27 Rational Arithmetic

Arithmetic Laws:

\begin{eqnarray*}
\frac{a}{b} + \frac{c}{d} & = & \frac{ad + bc}{bd} \\
\frac{a}{b} * \frac{c}{d} & = & \frac{ac}{bd}
\end{eqnarray*}

\begin{eqnarray*}
\frac{a}{b} - \frac{c}{d} & = & \frac{ad - bc}{bd} \\
\frac{a}{b} / \frac{c}{d} & = & \frac{ad}{bc}
\end{eqnarray*}

\begin{eqnarray*}
\frac{5}{4} + \frac{6}{7} & = & \frac{5*7 + 4*6}{4*7} = \frac{...
...\frac{5}{4} * \frac{6}{7} & = & \frac{5*6}{4*7} = \frac{15}{14}
\end{eqnarray*}

28 Rational Arithmetic...

29 Rational Arithmetic...


\begin{gprogram}
normRat :: Rat -> Rat \\
normRat (\_,0) = error(''Invalid!$\ba...
...xx \xxx b = gcd a b \\
normRat (-168,1176) $\Rightarrow$\ (-1,7)
\end{gprogram}

30 Rational Arithmetic...

The signum Function:


\begin{gprogram}
signum :: (Num a, Ord a) => a -> Int \\
signum n \xxx \vert \x...
... \xxx \vert \x n > 0 \xxx = 1 \\
\xxx \vert \x n < 0 \xxx = -1
\end{gprogram}

The gcd Function:
\begin{gprogram}
gcd :: Int -> Int -> Int \\
gcd x y = gcd' (abs x) (abs y) \\ ...
... \xxxx gcd' y (rem x y) \\
\\
gcd 78 42 \xxxxx $\Rightarrow$\ 6
\end{gprogram}

31 Rational Arithmetic...

Arithmetic:
\begin{gprogram}
negRat :: Rat -> Rat \\
negRat (a,b) = normRat (-a,b) \\
\\
...
...= normRat (a*c, b*d) \\
divRat (a,b) (c,d) = normRat (a*d, b*c)
\end{gprogram}
Examples:
\begin{gprogram}
\redtt{> addRat (4,5) (5,6)} \\
\x (49,30)
\end{gprogram}

32 Rational Arithmetic...

Relational Comparison:
\begin{gprogram}
eqRat :: Rat -> Rat -> Bool \\
eqRat (a,0) (c,d) = err \\
eqR...
...(a,b) (c,d) = (a*d == b*c) \\
\x where err = error ''Invalid!''
\end{gprogram}

Examples:
\begin{gprogram}
\redtt{> eqRat (4, 0) (4, 1)} \\
\x Invalid! \\
\redtt{> eqRa...
..., 5)} \\
\x True \\
\redtt{> eqRat (4, 5) (4, 6)} \\
\x False
\end{gprogram}


Exercises


33 Homework

Examples:
\begin{gprogram}
split [(1,''a''),(2,''b''),(3,''c'')] \\
\x $\Rightarrow$\ ([1...
...se),(3,False)] \\
\x $\Rightarrow$\ ([1,2,3],[True,False,False])
\end{gprogram}

34 Homework

\begin{eqnarray*}
(a_1,a_2,a_3)+(b_1,b_2,b_3) & = & (a_1+b_1,a_2+b_2,a_3+b_3) \\...
...(b_1,b_2,b_3) & = &
(a_2b_3-b_2a_3,a_3b_1-a_1b_2,a_1b_2-a_2b_1)
\end{eqnarray*}

35 Homework...

  1. Now model $3\times3$ matrices as triples of Vector.
  2. Define a function scale'm that scales a matrix m by a float s, i.e. multiplies all elements by s.
  3. Define a function add'm that adds two matrices a and b together to form a new matrix c, i.e. $c_{i,j} = a_{i,j}+b_{i,j}$.
  4. Define a function transpose'm m that turns the rows of a matrix m into columns, and vice versa, i.e. $t_{i,j} = m_{j,i}$.



Christian S. Collberg
2005-09-07