Chapter 4ΒΆ

  • Pattern matching is shown with the example in factorial.hs
  • We should always try to have a catch-all pattern in order to avoid errors.
  • Catch-all examples
first :: (a,b,c) -> a
first(x,_,_)    = x

second :: (a,b,c) -> b
first(_,y,_)    = y
  • We can pattern match in list comprehensions. If a match fails, it ignores and moves to the next one:
let xs = [(1,3), (4,5), (7,8)]
[a+b | (a,b) <- xs]
  • You can write patterns for breaking up something into names whilst still keeping a reference to the whole thing:
capital :: String -> String
capital "" = "Empty string"
capital all@(x:xs) = "The first letter of" ++ all ++ "is" ++ x
  • Pipes | in functions which are akin to if statements:
bmiTell :: (RealFloat a) => a -> String
bmiTell weight height
    | weight / height ^ 2<= 18.5 = "You're underweight"
    | weight / height ^ 2<= 28 = "Normal"
    | otherwie = "You're are a whale."
  • There is no = after the function name and its parameters before the first guard.
  • Instead of repeating across the code base we can use where:
bmiTell :: (RealFloat a) => a -> String
bmiTell bmi
    | bmi <= skinny = "You're underweight"
    | bmi <= normal = "Normal"
    | otherwie = "You're are a whale."
    where bmi = weight / height ^ 2
          skinny = 18.5
          normal = 25.0
  • The where does not pollute other namespaces. And pattern matching can be used in where

  • let <bindings> in <expression> are similar to where except
    • they are expressions themselves.
    • they can be used by functions in local scope:
    (let (a,b,c) = (1,2,3) in a+b+c) * 100 -- 600
    
    [let square x = x * x in (square 5, square 3, square 2)] -- [(25,9,4)]
    
    • You can put let in list comprehensions:
    calcBmis :: (RealFLoat a) => [(a,a)] -> [a]
    calcBmis xs = [bmi | (w,h) <- xs, let bmi = w/h ^ 2, bmi > 25.0]
    
  • We can do pattern matching for case expressions:

describeList :: [a] -> String
describeList xs = "The list is" ++ case xs of [] -> "empty"
                                              [x] -> "singleton list"
                                              [xs] -> lomger list