# Haskell Chapter 3, Part II. Topics  Guards  Where  Let  Case (not emphasized)

## Presentation on theme: "Haskell Chapter 3, Part II. Topics  Guards  Where  Let  Case (not emphasized)"— Presentation transcript:

Topics  Guards  Where  Let  Case (not emphasized)

Guards

Guarded Command Language  Proposed by Dijkstra  Statement of the form G -> S  The guard is a proposition, must be true for statement to execute  Purpose: to support a new programming methodology that supported verification (correctness) during development  Basic Idea: if the order of evaluation is not important, the program should not specify one. All guards are evaluated, if more than one are true, choose one non-deterministically.  But in Haskell, they are evaluated top-down… more like an if-else from: http://en.wikipedia.org/wiki/Guarded_Command_Languagehttp://en.wikipedia.org/wiki/Guarded_Command_Language

Haskell Guards bmiTell :: Double -> String bmiTell bmi | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedy normal. Pffft. " | bmi <= 30.0 = "You're fat! Lose some weight." | otherwise = "You're a whale, congratulations!“  At least one must evaluate to true, else error.

More examples  Guards can take two parameters max' :: (Ord a) => a -> a -> a max' a b | a <= b = b | otherwise = a myCompare :: (Ord a) => a-> a-> Ordering a `myCompare` b | a == b = EQ | a <= b = LT | otherwise = GT

where

 purpose: avoid calculating same value multiple times  scope: only within function  defined at end of function, visible to all guards bmiTell :: Double -> Double -> String bmiTell weight height | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedy normal. Pffft. " | bmi <= 30.0 = "You're fat! Lose some weight." | otherwise = "You're a whale, congratulations!" where bmi = (weight / height ^2) * 703

or even more “where” clauses  Names must line up! bmiTell' :: Double -> Double -> String bmiTell' weight height | bmi <= skinny = "You're underweight, you emo, you!" | bmi <= normal = "You're supposedy normal. Pffft. " | bmi <= fat = "You're fat! Lose some weight." | otherwise = "You're a whale, congratulations!" where bmi = (weight / height ^2) * 703 skinny = 18.5 normal = 25.0 fat = 30.0

limits to where  where bindings are not shared across different function bodies. So this does not work! greet :: String -> String greet "Juan" = niceGreeting ++ "Juan" greet "Fernando" = niceGreeting ++ "Fernando" greet name = badGreeting ++ name where niceGreeting = "Hello, so nice to see you, " badGreeting = "Oh, it you..."

Pattern matching with where initials :: String -> String -> String initials firstname lastname = [f] ++ ". " ++ [l] ++ "." where (f:_) = firstname (l:_) = lastname

functions in where clause calcBmis :: [(Double, Double)] -> [Double] calcBmis xs = [bmi w h | (w, h) <- xs] where bmi weight height = (weight / height ^2) * 703 -- try calcBmis [(120, 62), (150, 79)]

let

 lets are expressions  allow you to bind variables  very local (don’t span guards)  can be used in pattern matching cylinder :: Double -> Double -> Double cylinder r h = let sideArea = 2 * pi * r * h topArea = pi * r ^ 2 in sideArea + 2 * topArea

more let  Introduce function in a local scope threeSquares = let square x = x * x in (square 5, square 3, square 2)  Bind to value aFormula = 4 * (let a = 9 in a + 1) + 2  Pattern match to access list/tuple components threeTimesHundred = (let (a,b,c) = (1,2,3) in a+b+c) *100  Use in list comprehensions calcBmis' :: [(Double, Double)] -> [Double] calcBmis' xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2]

let in GHCi  let binds names that can be used throughout GHCi session

let vs. where  where  is part of a syntactic construct (used in guards)  can be used to share bindings across parts of a function that are not syntactically expressions  let is an expression  expressions have values  let can be used almost anywhere in code … anywhere an expression can occur  but the scope of a let is only the expression which it encloses.  let y = a*b f x = (x+y)/y in f c + f d

case

case expression describeList :: [a] -> String describeList ls = "The list is " ++ case ls of [] -> "empty" [a] -> "singleton" xs -> " longer"

play and share 1. cookTemp takes a string and returns a cook temperature (“Slow” = 350, “Medium” = 400, “Get ‘Er Done” = 450, otherwise 250) 2. cookTemp2 takes an integer and returns a string. Do the reverse of the above, use a where clause. Use inequalities. 3. greet takes a list in the form [“Cyndi”,”Ann”,”Rader”] and displays “Hello Cyndi Rader”. Use a where clause. Do it again with a let clause. 4. myInfo. Takes a nested list such as: [["Cyndi", "Rader"], ["Golden", "CO"]] or [["Cyndi", "Rader"]]. If the list contains both name and location (i.e., length 2), print “firstname lives in city” otherwise print “firstname lives somewhere”. Use a where clause for firstname and city 5. sumUsage takes a list of numbers that represent KB (e.g., from a directory) and creates the sum in MB (use a let function to do the conversion). 6. boo takes a list. If the list has four elements, add the first and third and multiply by 100. If the list has three elements, add the first and second and multiply by 100. (why? just for pattern matching practice)

Download ppt "Haskell Chapter 3, Part II. Topics  Guards  Where  Let  Case (not emphasized)"

Similar presentations