H. Conrad Cunningham
23 October 2018
Copyright (C) 2017, 2018, H. Conrad Cunningham
Acknowledgements: I originally created these slides in Fall 2017 to accompany what is now Chapter 17, Higher Order Function Examples, in the 2018 version of the textbook Exploring Languages with Interpreters and Functional Programming.
Browser Advisory: The HTML version of this document may require use of a browser that supports the display of MathML. A good choice as of October 2018 is a recent version of Firefox from Mozilla.
Code: The Haskell module for this chapter is in HigherOrderExamples.hs.
Examine other useful functions from the Prelude library (list-breaking operators, list-combining operators)
Explore additional higher-order function examples (rational arithmetic, merge sort)
Remove blank spaces from beginning of string
For all finite lists xs and
predicates p on same type:
    span' :: (a -> Bool) -> [a] -> ([a],[a]) -- span in Prelude
    span' _ xs@[]      =  (xs, xs)
    span' p xs@(x:xs')
        | p x          =  let (ys,zs) = span' p xs' in (x:ys,zs)
        | otherwise    =  ([],xs)
    break' :: (a -> Bool) -> [a] -> ([a],[a]) -- break in Prelude 
    break' p =  span (not . p) For all finite lists xs and
predicates p on same type:
    zipWith' :: (a->b->c) -> [a]->[b]->[c] -- zipWith in Prelude
    zipWith' z  (x:xs)  (y:ys) = z x y : zipWith' z xs ys 
    zipWith' _  _     _        = []
    zip'' :: [a] -> [b] -> [(a,b)]  -- zip
    zip'' = zipWith' (\x y -> (x,y)) 
    zip''' = zipWith (,) -- same as zip''Scalar product of vectors
zipWith3 for
triples; Data.List has
zipWith4
zipWith7 for 4-to 7-tuplesAbove can be reimplemented/extended using higher order functions
    compareRat :: (Int -> Int -> Bool) -> Rat -> Rat -> Bool 
    compareRat r x y = r (numer x * denom y) (denom x * numer y) 
    eqRat,neqRat,ltRat,leqRat,gtRat,geqRat :: Rat -> Rat -> Bool 
    eqRat  = compareRat (==) 
    neqRat = compareRat (/=) 
    ltRat  = compareRat (<)
    leqRat = compareRat (<=) 
    gtRat  = compareRat (>)
    geqRat = compareRat (>=) If list fewer than two elements, sorted
Otherwise split into two half-length sublists, sort each
Merge two ascending sublists into ascending list
    msort :: Ord a => (a -> a -> Bool) -> [a] -> [a]
    msort _    []         = []
    msort _    [x]        = [x]
    msort less xs = merge less (msort less ls) (msort less rs)
        where n       = (length xs) `div` 2 
              (ls,rs) = splitAt n xs
              merge _ [] ys     = ys
              merge _ xs []     = xs
              merge less ls@(x:xs) rs@(y:ys) 
                  | less x y  = x : (merge less xs rs)
                  | otherwise = y : (merge less ls ys)    msort :: Ord a => (a -> a -> Bool) -> [a] -> [a]
    msort _    []         = []
    msort _    [x]        = [x]
    msort less xs = merge less (msort less ls) (msort less rs)
        where n       = (length xs) `div` 2 
              (ls,rs) = splitAt n xs
              merge _ [] ys     = ys
              merge _ xs []     = xs
              merge less ls@(x:xs) rs@(y:ys) 
                  | less x y  = x : (merge less xs rs)
                  | otherwise = y : (merge less ls ys)Under what circumstances does msort less xs terminate
normally?
What is time complexity of msort less xs? space
complexity?
List-breaking and list-combining operators
Rational arithmetic with higher order functions
Merge sort
The Haskell module for this chapter is in HigherOrderExamples.hs.