# Lecture 2 — 2015-09-07

``module Lec02 where``

We added this statement so that we could use definitions from Lec01.

``import Lec01 ``

We started by writing some functions over the `IntTree` structure that appears in the homework.

``````data IntTree =
Empty
| Node IntTree Int IntTree
deriving Show

leaf :: Int -> IntTree
leaf v = Node Empty v Empty

inorder :: IntTree -> [Int]
inorder Empty = []
inorder (Node l v r) = inorder l ++ [v] ++ inorder r

preorder :: IntTree -> [Int]
preorder Empty = []
preorder (Node l v r) = [v] ++ preorder l ++ preorder r

height :: IntTree -> Int
height Empty = 0
height (Node l _ r) = 1 + max (height l) (height r)``````

It took a minute to remember our BST invariants, but we wrote a simple lookup function.

``````memberBST :: Int -> IntTree -> Bool
memberBST _ Empty = False
memberBST v (Node l v' r)
| v == v' = True
| v < v' = memberBST v l
| v > v' = memberBST v r``````

Next, we tried to think about what it means for a tree to be balanced. We derived some requirements on the board and translated pretty directly to Haskell—nice!

``````balanced :: IntTree -> Bool
balanced Empty = True
balanced (Node l _ r) =
balanced l && balanced r &&
abs (height l - height r) <= 1``````

Once we tested on some bigger trees, we decided this was a bit too slow.

``````bigBalancedTree :: Int -> IntTree
bigBalancedTree 0 = Empty
bigBalancedTree n =
Node (bigBalancedTree (n-1)) 0 (bigBalancedTree (n-1))

bigUnbalancedTree :: Int -> IntTree
bigUnbalancedTree n
| n <= 0 = Node Empty 0 \$ Node Empty 1 \$ Node Empty 2 Empty
| even n = Node (bigUnbalancedTree (n-2)) 0 (bigUnbalancedTree (n-1))
| otherwise = Node (bigUnbalancedTree (n-1)) 0  (bigUnbalancedTree (n-2))``````

We rewrote our function to carefully computer balanced-ness and height at the same time, using pairs.

``````balanced' :: IntTree -> (Bool,Int)
balanced' Empty = (True,0)
balanced' (Node l _ r) =
let (bl,hl) = balanced' l in
let (br,hr) = balanced' r in
(bl && br && abs (hl - hr) <= 1, 1 + max hl hr)``````

After running `:set +s` to get some performance stats, we played with some other performance-oriented code.

We saw two ways of writing auxiliary functions. At the top level:

``````fib' :: Int -> Int
fib' n = fibAux n 1 1

fibAux :: Int -> Int -> Int -> Int
fibAux 0 f1 f2 = f1
fibAux 1 f1 f2 = f2
fibAux n f1 f2 = fibAux (n-1) f2 (f1+f2)``````

And in a `where` clause:

``````fib'' :: Int -> Int
fib'' n = fibAux n 1 1
where fibAux :: Int -> Int -> Int -> Int
fibAux 0 f1 f2 = f1
fibAux 1 f1 f2 = f2
fibAux n f1 f2 = fibAux (n-1) f2 (f1+f2)``````

I confusingly used the name `loop` at first. There’s no `loop` keyword in Haskell! It was just a name! A rose by another name would smell just as sweet.

We also looked at some lazy evaluation. First we had to check out some polymorphic functions, like `id` (of type `a -> a`) and `map` (of type `(a->b)->[a]->[b]`), and then `zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]`, which led us to this incredible looking definition of the Fibonacci series:

``````fibs :: [Int]
fibs = 1:1:(zipWith (+) fibs (tail fibs))``````

The secret sauce in the above definition is lazy evaluation, which we’ll look at more later in the semester. If it didn’t make sense, don’t worry! We’ll see a bit more on Wednesday, and then more formally next week.

Finally, there was some talk about so-called “algebraic” datatypes, where we could define non-recursive datatypes using either the `data`-style definitions or using `Either` and tuples/pairs `(,)`.

``````type Line' = Either Float (Float,Float)

mkLine :: Point -> Point -> Maybe Line
mkLine p1 p2 =
if xCoord p1 == xCoord p2
then if yCoord p1 == yCoord p2
then Nothing
else Just \$ Vert \$ xCoord p1
else
let m = (yCoord p1 - yCoord p2) /
(xCoord p1 - xCoord p2) in
let b = yCoord p1 - (m * xCoord p1) in
Just \$ Sloped m b

either' :: (a -> c) -> (b -> c) -> Either a b -> c
either' l r (Left a) = l a
either' l r (Right b) = r b``````

As a final puzzle, we thought about how you might write down the algebraic datatype for `IntTree`—it was recursive! We’ll look at these kinds of recursive definitions in more detail later in the course.