1 / 15

Com2010 - Functional Programming Higher Order Functions and Computation Patterns (II) Marian Gheorghe Lecture 11

Com2010 - Functional Programming Higher Order Functions and Computation Patterns (II) Marian Gheorghe Lecture 11 Module homepage Mole & http://www.dcs.shef.ac.uk/~marian. com2010. © University of Sheffield. Summary. 18. Higher-Order Functions and Computation Patterns

twyla
Download Presentation

Com2010 - Functional Programming Higher Order Functions and Computation Patterns (II) Marian Gheorghe Lecture 11

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Com2010 - Functional Programming Higher Order Functions and Computation Patterns (II) Marian Gheorghe Lecture 11 Module homepage Mole & http://www.dcs.shef.ac.uk/~marian com2010 ©University of Sheffield

  2. Summary 18. Higher-Order Functions and Computation Patterns 18.3 … primitive recursion 18.4 Efficiency and recursion patterns 18.5 Partial functions and errors 18.6 More higher-order on lists com2010 ©University of Sheffield

  3. Primitive recursion - example Iterations of different functions: f_1, f_2, …,f_n Example. The function fact(n) = n! may be obtained as 1  *2  2  *3 …  *n  n! or similar to get [1, 2, …, n] Obs. At step n we multiply by n or append n to the list. fact :: Int -> Int -- construct n! fact n | n == 0 = 1 | n > 0 = fact(n-1) * n natList :: Int -> [Int] -- constructs seq of naturals natList n | n == 0 = [] | n > 0 = natList (n-1) ++ [n] com2010 ©University of Sheffield

  4. Primitive recursion - pattern The pattern of primitive recursion: primRec::(Int->a->a)->a->Int->a -- 1st param: iter function, depends on iteration stage -- 2nd param: initial value -- 3rd param: iteration length primRec f x n | n==0 = x | n>0 = f n (primRec f x (n-1)) Examples myFact :: Int ->Int myFact = primRec (\n x -> x*n) 1 myNatList ::Int -> [Int] myNatList = primRec (\n x -> x++[n]) [] com2010 ©University of Sheffield

  5. Efficiency of recursion patterns Fibonacci sequence: fib :: Int -> Int – nice, simple, but inefficient (exp in n) fib n | n == 0 = 0 | n == 1 = 1 | n > 1 = fib(n-2) + fib(n-1) Fibonacci sequence; efficient version fibNextStep :: (Int, Int) -> (Int, Int) fibNextStep (x, y) = (y, x + y) -- uses myIter iteration function; efficient (linear in n) fastFib :: (Int -> Int) -- fast Fibonacci sequence fastFib = fst . (myIter fibNextStep (0,1)) Run fib, fastFib for 30 and watch the time!! com2010 ©University of Sheffield

  6. Generality vs efficiency Iteration and primitive recursion are two • general • powerful • elegant abstract mechanisms When fast algorithms are requested then less general solutions may be more efficient Ex:fib 20 makes 399209 reductions Whereas fastfib 20 makes 417 reduction com2010 ©University of Sheffield

  7. Partial functions and errors Simple examples include • attempts to divide by 0, to take the square root of a negative number, or the head of an empty list. • applying a function defined by (primitive) recursion on natural numbers to negative numbers (fib(-2)). • applying a function to an input value that is not caught by any pattern or guard in any of the function's definition equations (non-exhaustive patterns or guards). A hierarchy of` error treatment is studied com2010 ©University of Sheffield

  8. Errors: infinite loops; missing condition The function definition naiveFib :: Int -> In -- may loop naiveFib 0 = 0 naiveFib 1 = 1 naiveFib n = naiveFib(n-1) + naiveFib(n-2) When execute naiveFib with argument -3, naiveFib (-3) Error: control stack overflow!! fib :: Int -> Int -- may show run-time error fib 0 = 0 fib 1 = 1 fib n | n > 1 = fib(n-1) + fib(n-2) Run-time error when a value outside the range is used com2010 ©University of Sheffield

  9. Program abortion A simple example using error built-in function newFib :: Int -> Int -- may produce error message newFib 0 = 0 newFib 1 = 1 newFib n | n > 1 = newFib(n-1) + newFib(n-2) | otherwise = error( "\nError in newFib:Fibonacci " ++"function cannot \nbe applied to" ++" negative integer “ ++show(n) ++"\n") When newFib (-3) is used then an error will be displayed com2010 ©University of Sheffield

  10. Dummy values (1) Exceptional inputs can be covered by defining natural dummy results. Consider the Fibonacci sequence 0, 1, 1, 2, 3, 5, 8, … again. It would appear natural to extend the sequence into the negative indices by repeating 0: …, 0, 0, 0, 0, 1, 1, 2, 3, 5, 8, … i.e. we define fib n = 0, for negative n. So, 0 would be the dummy result for negative inputs. This would give us the following implementation: extFib :: Int -> Int -- extends 0's leftwards extFib 0 = 0 extFib 1 = 1 extFib n | n > 1 = extFib(n-1) + extFib(n-2) | otherwise = 0 com2010 ©University of Sheffield

  11. Dummy values (2) A better variant using dummy values symFib :: Int -> Int -- satisfies recursion law symFib 0 = 0 symFib 1 = 1 symFib n | n > 1 = symFib(n-1) + symFib(n-2) | otherwise = symFib(n+2) - symFib(n+1) SymFib(-1)=1, symFib(-2)=-1, SymFib (-3)=2; ie … 2, -1, 1, 0, 1, 1, 2,… etc Guess what symFib is doing com2010 ©University of Sheffield

  12. Exception handling To trap and process errors employ an explicit exception handling technique based on error types defined using algebraic types data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show) The type Maybe ais simply the type aextended by an error value Nothing. Any function gthat uses the result of another function may be transformed so it accepts an argument of type Maybe arather than a. This is where the error handling occurs. We can transmit the error through g trap the error within g. com2010 ©University of Sheffield

  13. Transmit (map) an error It lifts the function g :: a -> b to a function mapMaybe g :: Maybe a -> Maybe b mapMaybe :: (a->b) -> Maybe a-> Maybe b mapMaybe g Nothing = Nothing mapMaybe g (Just x) = Just (g x) Example mapMaybe (*3) (my_nth 5[1,2,3]) ⇒ Nothing mapMaybe (*3) (my_nth 2[1,2,3]) ⇒ Just 9 If, however, we lift the function g::a -> bto a function of type Maybe a -> bthen we are trapping the error. com2010 ©University of Sheffield

  14. Trap an error trapMaybe dummy g :: Maybe a -> b trapMaybe :: b->(a->b) -> Maybe a-> b trapMaybe dummy g Nothing = dummy trapMaybe dummy g (Just x) = g x Error handling. Steps: • Error identification (use type Maybe a) • Error mapping (lift g to mapMaybe) • Error trapping (lift g to trapMaybe) com2010 ©University of Sheffield

  15. Example Nothing trapMaybe dummyInt (1+)(mapMaybe (*3)(my_nth5[1,2,3]))  dummyInt integer value trapMaybe dummyInt (1+)(mapMaybe (*3)(my_nth2[1,2,3]))  10 mapMaybe either sends up Nothing or Maybe value trapMaybe either produces a dummy_value or transforms Maybe value into (1+) value com2010 ©University of Sheffield

More Related