12/8/14 ¡ CSCI-2325 Functional Programming with Haskell Mohammad T . Irfan Functional Programming u Mimic mathematical functions u No variables in C/Java sense u No assignment statements in C/Java sense u How about loops? u Context-independent u Referential transparency u Other prime features u Functions are first-class citizens u Extensive polymorphism u List types and operators u Recursion 1 ¡
12/8/14 ¡ Functional Programming “Backus’s apology for creating FORTRAN” Interesting facts: LISP and LISP Machine John McCarthy Knight machine LISP(1960) (1980s) 2 ¡
12/8/14 ¡ Theoretical foundation: λ calculus u Optional reading u Scott’s section 11.2.4* (on Blackboard) u Alonzo Church (1941) u λ expression u Reductions u Example u λ x . x * x * x u Evaluation: ( λ x . x * x * x) 2 produces 8 Haskell 3 ¡
12/8/14 ¡ Resources u Installation u http://www.haskell.org/platform/ u Haskell (GHCi) commands u http://www.haskell.org/ghc/docs/7.4.1/html/ users_guide/ghci-commands.html u Learning u Best book: Miran Lipovaca’s Learn You a Haskell for Great Good! u http://learnyouahaskell.com/ (free online version) u Useful how-to page u http://www.haskell.org/haskellwiki/Category:How_to u Other resources: http://www.haskell.org/haskellwiki/Learning_Haskell 4 ¡
12/8/14 ¡ Haskell Warm-up exercises Elementary functions u Make a myFunctions.hs file and define the following functions in it u doubleMe x = x + x u addSquares x y = x*x + y*y u Using the terminal go to the folder of that .hs file u Execute this command: ghci u Load the .hs file u :load myFunctions.hs (or, :l myFunctions.hs) u Use your functions u addSquares 5 10 u If you change the .hs file => Execute :r to reload 5 ¡
12/8/14 ¡ Announcement u Extension for Rails project u Due this Friday u Haskell and Prolog assignments u Both due on December 19 if-then-else u Indentation is important if boolean then expr1 else expr2 u Same line is fine if boolean then expr1 else expr2 u else is a must! Following doesn’t make sense: u let x = if a then b u Nested if? Yes! u Close alternative to if-then-else u “guard” – not exactly the same 6 ¡
12/8/14 ¡ Input and output u Problem: Guess a number guessNumber num = do putStrLn "Enter your guess:" guess <- getLine -- binds the input to guess if read guess < num then do putStrLn "Too low!" guessNumber num else if read guess > num then do putStrLn "Too high!" guessNumber num else do putStrLn "You Win!" Problem: calculate factorial of n Version 1 – note indentation factorialV1 n = if n == 0 then 1 else if n > 0 then n * factorialV1(n-1) else 0 7 ¡
12/8/14 ¡ Factorial Version 2 – using guard u factorial n | n == 0 = 1 | n > 0 = n * factorial (n-1) -- why not factorial n – 1 ? Guard u Try this: factorial 100 Problem: n-th Fibonacci number fib n | n == 0 = 1 | n == 1 = 1 | n > 1 = fib (n-1) + fib (n-2) | otherwise = 0 Alias for True u Can you solve it using if-then-else? 8 ¡
12/8/14 ¡ List u Want: evens = [0, 2, 4, 6, 8, 10] u In terminal (ghci) u let evens = [0, 2 .. 10] u evens = [2*x | x <- [0..5] ] u Infinite list u let allEvens = [0, 2 ..] Are these assignment statements? Anatomy of a list u Two parts u head u List of the remaining elements (AKA tail) u Functions head and tail return these u head evens u tail evens u Joining head and tail by : operator u 0 : [2, 4 .. 10] will give [0, 2, 4, 6, 8, 10] u Reference u http://www.haskell.org/haskellwiki/How_to_work_on_lists 9 ¡
12/8/14 ¡ Problem: sort a list (low to high) sort [] = [] Empty list sort (head:remainingList) = sort [b | b <- remainingList, b < head] ++ [head] ++ sort [b | b <- remainingList, b >= head] List generator More list examples u Example: Factors of a number n u factors n = [f | f <- [1 .. n], mod n f == 0] u Example: Compute ALL prime numbers! u primes = primeGen' [2 ..] where primeGen' (p:xs) = p : primeGen' [q | q <- xs, mod q p /= 0] u Getting the first 10 prime numbers u take 10 primes Lazy evaluation u Side note: This is not really the sieve of Eratosthenes http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP .pdf 10 ¡
12/8/14 ¡ Problem solving using Haskell Main ingredient: recurrence relation u Recursive sum u recSum [] = 0 recSum (x:xs) = x + recSum xs u Built-in function that does the above: sum u sum [1 .. 5] u Similar built-in function: product u factorial n = product [1 .. n] Higher-order function/ curried function u One function can be a parameter of another functions u One function can return another function Haskell Curry 11 ¡
12/8/14 ¡ Higher-order function/ curried function u In GHCI command area: let fun3 x y z = x+y-z -- 3 param function fun3 1 2 3 – outputs 0 u This is how Haskell deals with the fun3 function: let fun2 = fun3 1 -- 2 param function let fun1 = fun2 2 -- 1 param function fun1 3 -- outputs 0 Comment n-queens problem queens n = solve n where solve k | k <= 0 = [ [] ] | otherwise = [ h:partial | partial <- solve (k-1), h <- [0..(n-1)], safe h partial] safe h partial = and [ not ( checks h partial i) | i <- [0..(length partial - 1)]] checks h partial i = h == partial!!i || abs(h - partial!!i) == i+1 12 ¡
12/8/14 ¡ 3 most useful built-in functions 1. map function list u map ( > 0) [2, -50, 100] -- à [True, False, True] u Equivalent: [ x > 0 | x <- [2, -50, 100] ] u map (`mod` 2) [13, 14, 15] -- à [1, 0, 1] 2. filter predicate/condition list u Examples u Sorting function (from last class) qsort [b| b<-xs, b<x] qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ Difference between qsort (filter (>= x) xs) map and filter? 3. Fold: produces single value from a list (From Haskell.org) Binary function Accumulator! u foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs u foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) u Example u foldl (-) 1 [2, 3, 4] u foldr (-) 1 [2, 3, 4] u anyTrue = foldr (||) False [True, True ..] u anyTrue = foldl (||) False [True, True ..] 13 ¡
12/8/14 ¡ Problem: Evaluate Polish prefix expression u 10 + (15 – 5) * 4 u + 10 * - 15 5 4 u 10 + 15 – 5 * 4 u + 10 - 15 * 5 4 u Input: String (list of characters) of Polish prefix expression u Output: Value of expression u Solution u Reverse the expr foldl u Traverse it from left to right u Stack operations (implement by a list: head is TOS) u If the current string is an operator, pop the top two operands and push the result of applying the operator Solution evaluate expr = head(foldl stackOperation [] � � � � � (reverse(words(expr)))) � where � stackOperation (x:y:xs) curString � | curString == "+" = (x+y):xs � � � � | curString == "-" = (x-y):xs � � � � | curString == "*" = (x*y):xs � stackOperation xs curString = read curString:xs � 14 ¡
12/8/14 ¡ Alternative solution evaluatePrefix expr � � = head ( foldl f [] ( reverse (words expr) ) � � � � ) � � where � f (x:y:ys) "*" = (x*y):ys � � � � � � f (x:y:ys) "+" = (x+y):ys � � � � � � f (x:y:ys) "-" = (x-y):ys � � � � � � f xs str = read str:xs � 15 ¡
Recommend
More recommend