Lecture 3
types :: type1 → type2
F12
, then click ConsoleF12
, then click ConsoleCtrl+Shift+k
↓ , PgDn , n , j 
next slide 
↑ , PgUp , p , k 
prev slide 
Esc 
enables ctrl+f globally 
Run it from the terminal

Or run ghci, then load the file

Implement factorial
A  B  C  D  E  F  G  H  I  J  ... 
 Most popular solution
facA n = if n > 1
then n * facA(n1)
else n
 Right tools for the right job
facB n = product [1..n]
 Oh, you.
facC n = foldr (*) 1 [1..n]
 Sophomore Haskell programmer
 (studied Scheme as a freshman)
 http://willamette.edu/~fruehr/haskell/evolution.html
facD = (\(n) >
(if ((==) n 0)
then 1
else ((*) n (facD (() n 1)))))
 Memoizing Haskell programmer
 http://willamette.edu/~fruehr/haskell/evolution.html
facs = scanl (*) 1 [1..]
facE n = facs !! n
 Iterative Haskell programmer
 (former Pascal programmer)
 http://willamette.edu/~fruehr/haskell/evolution.html
facF n = result (for init next done)
where init = (0,1)
next (i,m) = (i+1, m * (i+1))
done (i,_) = i==n
result (_,m) = m
for i n d = until d n i
 Continuationpassing Haskell programmer
 http://willamette.edu/~fruehr/haskell/evolution.html
facCps k 0 = k 1
facCps k n = facCps (k . (n *)) (n1)
facG = facCps id
 Boy Scout Haskell programmer
 http://willamette.edu/~fruehr/haskell/evolution.html
y f = f (y f)
facH = y (\f n > if (n==0) then 1 else n * f (n1))
 Combinatory Haskell programmer
 http://willamette.edu/~fruehr/haskell/evolution.html
s f g x = f x (g x)
k x y = x
b f g x = f (g x)
c f g x = f x g
y f = f (y f)
cond p f g x = if p x then f x else g x
facI = y (b (cond ((==) 0) (k 1)) (b (s (*)) (c b pred)))
 Listencoding Haskell programmer
 (prefers to count in unary)
 http://willamette.edu/~fruehr/haskell/evolution.html
arb = ()
listenc n = replicate n arb
listprj f = length . f . listenc
listprod xs ys = [ i (x,y)  x<xs, y<ys ]
where i _ = arb
facl [] = listenc 1
facl n@(_:pred) = listprod n (facl pred)
facJ = listprj facl
Bool
= False  True
Char
= 'a'  'b'  ...  'A'  'B'  ...
Int
= 2^{31}  ...  1  0  1  ...  2^{31}1
Integer
Double
Types always start with a capital letter
Haskell secretly infers that True
is a Bool
.
Prelude> :type True
True :: Bool
You can also explicitly use a type.
Prelude> 3 :: Int
3
Prelude> 3 :: Double
3.0
Prelude> head [1,2,3,4]
1
Prelude> :type head
head :: [a] > a
head
has the type List of a
's to just a
Prelude> fst ("left", "right")
"left"
Prelude> :type fst
fst :: (a, b) > a
fst has the type tuple of a
and b
to just a
"if a piece has the wrong shape, it simply won't fit"
Haskell  Python* 
What should be the type declaration for fac
?
(clear answer)
(show answer)
fac n = product [1..n]
fac :: Integer > Integer
fac n = product [1..n]
What's the type declaration for &&
?
(clear answer)
(show answer)
(&&) ::
(&&) :: Bool > Bool > Bool
How about :
?
(clear answer)
(show answer)
Prelude> 0:[1,2,3]
[0,1,2,3]
Prelude> :type (:)
Prelude> 0:[1,2,3]
[0,1,2,3]
Prelude> :type (:)
(:) :: a > [a] > [a]
(8:00 to 9:22)
A Typeclass lets you generalize a function.
For example, the lessthan sign can be used multiple ways.
10 < 20
'a' < 'b'
"aardvark" < "zzz"
[6,2,4] < [6,3,8]
Ord
Typeclassis used for things with total order
Prelude> :type (<)
Prelude> :type (<)
(<) :: a > a > Bool
Prelude> :type (<)
(<) :: Ord a => a > a > Bool
(clear answer)
(show incorrect answer)
(show answer)
Remember them from Java?
public class NumberUsedByLessThanSign implements Comparable {
...
}
Show
 representable as a string
Prelude> show 42
"42"
Enum
 enumerable in a list
Prelude> ['R'..'t']
"RSTUVWXYZ[\\]^_`abcdefghijklmnopqrst"
Num
 usable as a number
Prelude> 5.2 * 2.5
13.0
Functions with multiple arguments look funny.
The take
function has two arguments:
n
ls
and it produces the first n
elements of ls
Prelude> take 5 [1..]
[1,2,3,4,5]
The type declaration is
Prelude> :type take
take :: Int > [a] > [a]
Weird...
All Haskell functions take only one argument
at the take
function:
take :: Int > [a] > [a]
The >
operator is rightassociative
take :: Int > ([a] > [a])
take
actually has type of Int to a function
Every function technically has one argument.
Actually, this is really cool!
Prelude> :type take
take :: Int > [a] > [a]
Prelude> let takeFive = take 5
Prelude> :type takeFive
takeFive :: [a] > [a]
Prelude> takeFive [1..]
[1,2,3,4,5]
A function only depends on its aguments.
A type declaration is a strong promise.
Focus on what is done, not how.
Inherently modular
Elegant
Create mycode.hs
and write a function called zipTogether
 mycode.hs
 The 'zipTogether' function binds together two lists.
zipTogether :: [a] > [b] > [(a,b)]
 mycode.hs
 The 'zipTogether' function binds together two lists.
zipTogether :: [a] > [b] > [(a,b)]
zipTogether [] [] = []
zipTogether [] ys = []
zipTogether xs [] = []
zipTogether xs ys = (head xs, head ys):
(zipTogether (tail xs) (tail ys))
 mycode.hs
 The 'zipTogether' function binds together two lists.
zipTogether :: [a] > [b] > [(a,b)]
zipTogether [] [] = []
zipTogether [] ys = []
zipTogether xs [] = []
zipTogether (x:xs) (y:ys) = (x,y) : zipTogether xs ys
(clear answer)
(show answer 1)
(show answer 2)
Expected output:
Prelude> zipTogether [1,2,3] "abc"
[(1,'a'),(2,'b'),(3,'c')]
by the way, Haskell comes with zip
cipher
cipher :: [Char] > Int > [Char]
Prelude> cipher "hello" 13
"uryyb"
cipher :: [Char] > Int > [Char]
cipher [] _ = []
cipher (s:ss) n = (rotate s n) : (cipher ss n)
rotate :: Char > Int > Char
Now define this 'rotate' function
Bonus points for a cool solution!
Submit this week's homework form!