Introduction To Haskell Lecture 3

types :: type1 → type2

Using These Slides Every slide has a secret note. On Chrome : press F12 , then click Console

: press , then click On IE : press F12 , then click Console

: press , then click On Firefox: Ctrl+Shift+k



Shortcut Keys: ↓ , PgDn , n , j next slide ↑ , PgUp , p , k prev slide Esc enables ctrl+f globally Hi there! This is a secret lecture note. Every slide has a little blurb of text like this!

Haskell Programming Code lives in a file with a .hs extension



Open the file with GHCi Run it from the terminal $ ghci myfile.hs Or run ghci, then load the file $ ghci Prelude> :load myfile

Call your function through ghci This is just a review.

Previous Homework Implement factorial A B C D E F G H I J ... -- Most popular solution facA n = if n > 1 then n * facA(n-1) 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 -- Continuation-passing Haskell programmer -- http://willamette.edu/~fruehr/haskell/evolution.html facCps k 0 = k 1 facCps k n = facCps (k . (n *)) (n-1) 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 (n-1)) -- 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))) -- List-encoding 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 There's always multiple ways to implement any function.

Types 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 Think of these almost as Java types (int, String, etc).

Everything has a Type 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 '::' is pronounced 'has the type of'

Yes, Functions have a Type 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 'a' and 'b' here are called Type variables.

Like a Jigsaw Puzzle Analogy from Real World Haskell "if a piece has the wrong shape, it simply won't fit" Haskell Python* Bugs are usually caught at compile-time. The compiler knows the type of every value, so there is never ambiguity.

Google Tech Talk (8:00 to 9:22) The Haskell compiler tries to infer the type for you. If ambiguous, the programmer must specify the Type explicitly.

Typeclass A Typeclass lets you generalize a function. For example, the less-than sign can be used multiple ways. 10 < 20

'a' < 'b'

"aardvark" < "zzz"

[6,2,4] < [6,3,8] This is a type of polymorphism.

The Ord Typeclass is used for things with total order Prelude> :type ( Prelude> :type ( a -> Bool Prelude> :type ( a -> a -> Bool (clear answer) (show incorrect answer) (show answer) Less-than is a function that that takes two comparable things, and outputs a Bool.

Similar to Interfaces Remember them from Java? public class NumberUsedByLessThanSign implements Comparable { ... } A Typeclass gives a Type some property. For example, both Int and String are comparable, so they both has the type class of Ord.

Other Typeclasses Show - representable as a string Prelude> show 42 "42"

- representable as a string Enum - enumerable in a list Prelude> ['R'..'t'] "RSTUVWXYZ[\\]^_`abcdefghijklmnopqrst"

- enumerable in a list Num - usable as a number Prelude> 5.2 * 2.5 13.0 42 has the Show Typeclass because we can print it out as a String. Characters have the Enum Typeclass because we can put them in order of ASCII code. Numbers have the Num Typeclass because they can do number-like operations.

Have you noticed? Functions with multiple arguments look funny. The take function has two arguments: an integer, n

a list, 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... It appears like this function has one argument 'Int', and one output '[a]' with something in-between.

The Concept of Currying All Haskell functions take only one argument Take a moment to think about that statement.

You mind is about to be blown.

A Closer Look at the take function: take :: Int -> [a] -> [a]

The -> operator is right-associative take :: Int -> ([a] -> [a]) take actually has type of Int to a function So technically, 'take' has just one argument (something of type Int)

Partial Applications 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] Try it out yourself.

Functional and Pure A function only depends on its aguments. A type declaration is a strong promise. Focus on what is done, not how. Inherently modular Elegant I hope you're beginning to see why Haskell is a little different.

Get Our Hands Dirty 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 Zipping is actually used a lot in functional programming. Think of it as zipping together the x-y axes of a graph to plot points.