Lecture 4

#SyntaxSwag

### Using These Slides

#### Every slide has a secret note.

• On Chrome: press `F12`, then click Console
• On IE: press `F12`, then click Console
• On Firefox: `Ctrl+Shift+k`

### Shortcut Keys:

 `↓`, `PgDn`, `n`, `j` next slide `↑`, `PgUp`, `p`, `k` prev slide `Esc` enables `ctrl+f` globally

## Review

 Haskell is Purely functional Statically typed Lazy Data looks like Bool Int Char ...

Lists and Tuples are useful data structures

 List `[1,2,3]` Tuple `(1, "one")`

### More Review

Everything in Haskell has a Type

Here are some Type declarations.

``````
head :: [a] -> a -- gets the first element of a list

tail :: [a] -> [a] -- gets everything but the first element

last :: [a] -> a -- gets the last element of a list

init :: [a] -> [a] -- gets everything but the last element

(++) :: [a] -> [a] -> [a] -- concatenates two lists together

(:) :: a -> [a] -> [a] -- prepends an element to a list

fst  :: (a,b) -> a -- gets the first element of a tuple

snd  :: (a,b) -> b -- gets the second element of a tuple
``````

### Review of Homework 3

Implement a Caesar Cipher
 A B C D
``````
-- This example uses 'succ' to get next letter

cipher :: String -> Int-> String
cipher "" n = ""
cipher str n = rotate (head str) n : cipher (tail str) n

rotate :: Char -> Int -> Char
rotate c 0 = c
rotate c n = rotate (next c) (n-1)

next :: Char -> Char
next c = if c=='z' then 'a' else succ c
``````

## Pattern Matching

A function can have multiple patterns

``````
guess :: Int -> [Char]
guess 42 = "correct!"
guess x  = "wrong guess!"
``````

Each pattern has the same type declaration

#### Pattern Matching

• Patterns are matched in order, top-down

• Only the first matched pattern is evaluated

• The patterns must exhaust the entire domain

### What's wrong with this code?

``````
fib :: Int -> Int
fib n = fib(n-1) + fib(n-2)
fib 0 = 1
fib 1 = 1
``````

The base case is never hit.

The first pattern eats up everything!

∞ loop

### More Pattern Matching

You can even match lists using Construct

``````
head (firstItem : everythingElse) = firstItem
``````
``````
tail (x:xs) = xs
``````

### More Pattern Matching

Write a function to detect if a list is a palindrome

``````
isPal :: Eq a => [a] -> Bool

``````

### Pattern matching is powerful

We can define `fst` with pattern matching

``````
fst :: (a,b) -> a
fst (x,y) = x
``````

Try defining `head` with pattern matching

``````

``````

### Wildcard in Pattern Matching

• We can specify when a value is unused.

• The "_" symbol is called a wildcard in Haskell.

• This is how it's used:

• ``````

tail (_:xs) = xs
``````

### Error Handling

When GHCi is angry, it produces error messages through the `error` function.

``````
error :: [Char] -> a
``````

The official implementation of `head` is

``````
``````

*

## Guards

• Guards are clean `if` statements.

• Just like with pattern matching, order matters.

• A guard is introduced by the `|` symbol.

• And it's followed by a Bool expression.

• Then followed by the function body

• ``````
guessMyNumber x
| x > 27    = "Too high!"
| x < 27    = "Too low!"
| otherwise = "Correct!"
``````
`otherwise` is just a fancy word for `True`

### Guards

Guards are very powerful.

Anything done with pattern matching can be done with guards.

``````
| null xs   = error "list is empty"
| otherwise = xs !! 0
``````
`!!` is a function that gives an element at an index

### Variables

These are not like your typical Java variables

In Java or C++, you can redefine variables:

``````
x = 1;

...

x = 2;
``````

Mathematically, this makes no sense.

## Variables

Once defined, they can't change.

They can be used with the `let` keyword.

``````
slope (x1,y1) (x2,y2) = let dy = y2-y1
dx = x2-x1
in dy/dx
``````

Or with the `where` keyword.

``````
slope (x1,y1) (x2,y2) = dy/dx
where dy = y2-y1
dx = x2-x1
``````

## Whitespace

Code which is part of some expression should be indented further in than the beginning of that expression *
``````
Level-1
Level-2
Level-3
Level-3
Level-3
Level-2
Level-3
Level-3

Level-1
Level-2
Level-2

Level-1
``````
Don't use tab. Use spaces '` `'.

# Homework

## A Useful Tool

1. Fill out this week's form.
2. Convert between metric and imperial.

`convert :: (Double, [Char]) -> (Double, [Char])`

• m ↔ yd
• L ↔ gal
• kg ↔ lb
``````
Prelude> convert (1, "m")
(1.09361, "yd")
Prelude> convert (1, "L")
(0.264172, "gal")
Prelude> convert (1, "kg")
(2.20462, "lb")
``````