Download Presentation
## Programming Paradigms

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -

**Programming Paradigms**CPSC 449 Week 4 Prepared by : Mona Hosseinkhani, ArashAfshar Winter 2014 Department of Computer Science, University of Calgary**Pattern matching vs. guards in functions**• An example function using guards mystery :: Integer -> Integer -> Integer mystery x y | x==0 = y | otherwise = x • Same function using pattern matching(by two equations) mystery' :: Integer -> Integer -> Integer mystery' 0 y = y mystery' x _ = x • Equations are applied sequentially**Patterns and parentheses**Always parenthesized patterns and constructors • example: f x:xs = (f x):xs and not as f (x:xs) • function applications bind more tightly than any other operations**The case construction**• So far: pattern match over the arguments of functions • Case: pattern match over other values • example: Return the first digit in a string. firstDigit :: String -> Char firstDigitst = case (digits st) of [] -> '\0' (x:_) -> x where digits :: String -> Stringdigits st = [ ch | ch<-st , isDigitch] • case e of p1 -> e1 p2 -> e2 … pk -> ek**Testing re-implemented functions using QuickCheck**• Suppose we re-implement a function like sum which is implemented in the Prelude • Requirements: • Hide the “sum definition in Prelude” when importing Prelude import Prelude hiding (…,sum,…) • Test our re-implemented sum against the original sum by: import qualified Prelude**Testing re-implemented functions using QuickCheck**• Putting it together: module Chapter7 where import Prelude hiding (…,sum,…) import qualified Prelude import Test.QuickCheck sum = … our definition … prop_sum :: [Integer] -> Bool prop_sumxs = sum xs == Prelude.sumxs • This also can be used when we have two different implementations of a particular function.**Finding primitive recursive definitions**• Given the value of fun xs, how could we define fun (x:xs) from it? • example: • Suppose you have the function “:” a->[a]->[a] (add a single element to the front of a list) • [2,3,4] ++ [9,8] = [2,3,4,9,8] • 2 : ([3,4] ++ [9,8]) • How we can define “++” [a]->[a]->[a] from “:”?(Join two list together) (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x:(xs++ys)**Finding primitive recursive definitions**• More examples: • Testingwhethersomething is a member of a list elem' :: Integer -> [Integer] -> Bool elem' x [] = False elem' x (y:ys) = (x==y) || (elem' x ys) • To double every element of an integer list doubleAll :: [Integer] -> [Integer] doubleAllxs = [ 2*x | x<-xs] doubleAll' [] = [] doubleAll' (x:xs) = 2*x : doubleAll' xs**Finding primitive recursive definitions**• To select the even elements from an integer list selectEven :: [Integer] -> [Integer] selectEvenxs = [ x | x<-xs , isEven x ] selectEven' [] = [] selectEven' (x:xs) | isEven x = x : selectEven' xs | otherwise = selectEven' xs**General recursions over lists**• A general recursive function . . . • may have more than one base case • may have different arguments for different recursive calls • arguments to recursive calls may not be strictly smaller than arguments to the function itself • may recurs on multiple arguments**General recursions over lists**• More examples: • Zipping together two lists. zip :: [a] -> [b] -> [(a,b)] zip (x:xs) (y:ys) = (x,y) : zip xsys zip (x:xs) [] = [] zip [] zs = [] • Recurring on both arguments • Taking a given number of elements from a list take :: Int -> [a] -> [a] take 0 _ = [] take _ [] = [] take n (x:xs) | n>0 = x : take (n-1) xs take _ _ = error "PreludeList.take: negative argument” • Recurring on an integer and a list**Example: Text Processing**• How to justify a paragraph • Bottom-up vs. Top-down approach • [Char] Words Lines • An input file in haskell can be treated as a string of characters. • The `whitespace' characters. whitespace = ['\n','\t',’ ‘] • Get a word from the front of a string. getWord :: String -> String getWord [] = [] getWord (x:xs) | elem x whitespace = [] | otherwise = x : getWordxs**Example: Text Processing**• In a similar way, the first word of a string can be dropped. dropWord :: String -> String dropWord [] = [] dropWord (x:xs) | elem x whitespace = (x:xs) | otherwise = dropWordxs • To remove the whitespace character(s) from the front of a string. dropSpace :: String -> String dropSpace [] = [] dropSpace (x:xs) | elem x whitespace = dropSpacexs | otherwise = (x:xs)**Example: Text Processing**• Splitting a string into words. type Word = String splitWords :: String -> [Word] splitWordsst = split (dropSpacest) split :: String -> [String] split [] = [] split st = (getWordst) : split (dropSpace (dropWordst)) • Getting a line from a list of words. type Line = [Word] getLine :: Int -> [Word] -> Line getLinelen [] = [] getLinelen (w:ws) | length w <= len = w : restOfLine | otherwise = [] where newlen = len - (length w + 1) restOfLine = getLinenewlenws**Example: Text Processing**• Dropping the first line from a list of words. • dropLine :: Int -> [Word] -> Line • Splitting into lines splitLines :: [Word] -> [Line] splitLines [] = [] splitLinesws = getLinelineLenws: splitLines (dropLinelineLenws) • To fill a text string into lines, we write fill :: String -> [Line] fill = splitLines . splitWords**Question**hossem<at>ucalgary.ca