SlideShare a Scribd company logo
Real World Haskell:
     Lecture 2

   Bryan O’Sullivan


     2009-10-14
My homework, using only concepts from last week
   import Data . L i s t ( i s I n f i x O f )

   pattern = ” toast ”

   f o r m a t number l i n e = show number ++ ” : ” ++ l i n e

   g r e p number i n p u t
          = i f null input
            then [ ]
            e l s e i f i s I n f i x O f p a t t e r n ( head i n p u t )
                    then        f o r m a t number ( head i n p u t )
                             : g r e p ( number + 1 ) ( t a i l i n p u t )
                    else        g r e p ( number + 1 ) ( t a i l i n p u t )

   grepFromOne i n p u t = u n l i n e s ( g r e p 1 ( l i n e s i n p u t ) )

   main = i n t e r a c t grepFromOne
Wasn’t Haskell supposed to be “pretty”?




   That grep function sure didn’t look pretty to me!

   But what, specifically, is ugly about it?
       We repeat ourselves, using head and tail twice.
       There’s a mess of nested if /else badness going on.
Lists, revisited



   There are two ways to construct a list:
        An empty list
        []
        A non-empty list
        firstElement : restOfList

   We refer to [] and : as list constructors, since they construct list
   values.
Lists, constructed


   Knowing about these constructors, how might we construct a
   4-element list?
Lists, constructed


   Knowing about these constructors, how might we construct a
   4-element list?
       1 : 2 : 3 : 4 : []

   The bracketed notation we saw last week is syntactic sugar for the
   form above.

   In other words, any time you see this:
        [1,2,3,4]
   You can read it as this, and vice versa:
       1 : 2 : 3 : 4 : []
Lists, misconstrued



   Beginner mistake alert:
   A list must end with an empty list. So a construction like this
   makes no sense:
        ’a’ : ’b’ : ’c’

   How would we fix it up?
        ’a’ : ’b’ : ’c’ : []
Back to our roots


   Remember the fragment of square root code from last week?
   oneRoot a b c = (−b + ( b ˆ2 + 4∗ a ∗ c ) ) / ( 2 ∗ a )

   If we pass in a value of zero for a, the root is undefined, since we’d
   be dividing by zero.

   oneRoot a b c = i f a == 0
                   then (−b + ( b ˆ2 − 4∗ a ∗ c ) )
                           / (2∗ a )
                   e l s e e r r o r ” d i v i d e by z e r o ! ”
But...



   I don’t like that if , because how would we write this using
   mathematical notation?


                           −b ± (b 2 − 4ac)
           roots(a, b, c) =                            if a = 0
                                 2a
                         = undefined                  otherwise

   And . . . isn’t Haskell supposed to be mathematically inspired?
Introducing guards

   A guard is a Boolean expression preceded by a vertical bar
   character.

   oneRoot a b c
     | a /= 0            = (−b + ( b ˆ2 − 4∗ a ∗ c ) ) / ( 2 ∗ a )
     | o t h e r w i s e = e r r o r ” d i v i d e by z e r o ”


       Guards are evaluated in top-to-bottom order.
       For the first one that evaluates to True, the expression on the
       right of the = sign is used as the result of the function.
       The name otherwise is simply another name for True.
Using guards


   Here’s a second attempt at our grep function, this time using
   guarded expressions:
   g r e p number i n p u t
       | null input
             =        []
       | i s I n f i x O f p a t t e r n ( head i n p u t )
             =        f o r m a t number ( head i n p u t )
                  : g r e p ( number + 1 ) ( t a i l i n p u t )
       | otherwise
             =        g r e p ( number + 1 ) ( t a i l i n p u t )
How did this help?




   We got rid of the nested if expressions, and our “flatter” code is
   easier to follow.

   It’s still fugly and repetitive, though. What about head and tail ?
Pattern matching




   When we construct a list, the Haskell runtime has to remember
   what constructors we used.

   It goes a step further, and makes this information available to us.

   We can examine the structure of a piece of data at runtime using
   pattern matching.
Pattern matching on an empty list



   What’s the length of an empty list?

   myLength [ ] = 0

   This is a function of one argument.
   If that argument matches the empty-list constructor, our function
   returns the value 0.
Pattern matching on a non-empty list



   What’s the length of a non-empty list?

   myLength ( x : x s ) = 1 + myLength x s

   If our argument matches the non-empty-list constructor “:”, then:
       the head of the list is bound to the name x;
       the tail to xs;
       and the expression is returned with those bindings.
Aaaand it’s over to you


   Now that we know how pattern matching works, let’s do some
   super-simple exercises:

   Write versions of the head and tail functions:

   head     [1 ,2 ,3]
     == >   1
   tail     [ ’a’ , ’b’ , ’c ’]
     == >   [ ’b’ , ’c ’]

   Give your versions different names, or you’ll have a hard time
   trying them out in ghci.
Matching alternative patterns


   We combine our two pattern matches into one function definition
   by writing them one after the other:

   myLength [ ]         = 0
   myLength ( x : x s ) = 1 + myLength x s

   As with guards, pattern matching proceeds from top to bottom
   and stops at the first success.
       The RHS of the first pattern that succeeds is used as the
       body of the function.
Matching alternative patterns


   We combine our two pattern matches into one function definition
   by writing them one after the other:

   myLength [ ]         = 0
   myLength ( x : x s ) = 1 + myLength x s

   As with guards, pattern matching proceeds from top to bottom
   and stops at the first success.
       The RHS of the first pattern that succeeds is used as the
       body of the function.

   Question: What do you suppose happens if no pattern matches?
Over to you, part two

   And now that we know how to write function definitions that can
   deal with multiple patterns, another exercise:

   Write a version of the take function:

   take 3    [100 ,200 ,300 ,400 ,500]
     ==>     [100 ,200 ,300]
   take 3    [ ’a’ , ’b ’]
     ==>     [ ’a’ , ’b ’]
   take 3    []
     ==>     ???
Over to you, part two

   And now that we know how to write function definitions that can
   deal with multiple patterns, another exercise:

   Write a version of the take function:

   take 3    [100 ,200 ,300 ,400 ,500]
     ==>     [100 ,200 ,300]
   take 3    [ ’a’ , ’b ’]
     ==>     [ ’a’ , ’b ’]
   take 3    []
     ==>     ???

   Now use ghci to figure out what the drop function does, and
   write a version of that.
Metasyntactic variables


   Languages have their cultural habits, and Haskell is no exception.

   You’ll very often see the names used when pattern matching a list
   follow a naming convention like this:
       (x: xs)
       (y: ys)
       (d:ds)
   and so on.

   Think of the “s” suffix as “pluralizing” a name, so “x” (ex) is the
   head of the list, and “xs” (exes) is the rest.
Matching multiple patterns




   We can match more than one pattern at a time.

   Consider how we might add the elements of two vectors,
   represented as lists:

   sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s
   sumVec [ ]         []          = []
Combining pattern matching and guards


   Things start to get seriously expressive when we combine language
   features.

   Remember that bloated grep definition from earlier? Let’s put our
   new friends to work!

   grep n [ ]                      =      []
   grep n ( x : xs )
     | i s I n f i x O f pattern x =    format n x
                                      : g r e p ( n+1) x s
      | otherwise                   =   g r e p ( n+1) x s
What’s happening here?

   When we define a function, a pattern binds names to values. Given
   a list and a pattern (x: xs), if the list is non-empty, then x is bound
   to its head, and xs to its tail.
        Then each guard (if any) associated with that pattern is
        evaluated in turn, with those bindings in effect, until a guard
        succeeds.
        Once a guard succeeds, its RHS is used as the result, with the
        bindings from that pattern still in effect.
        If the pattern match fails, or no guard succeeds, we fall
        through to the next pattern and its guards.
What’s happening here?

   When we define a function, a pattern binds names to values. Given
   a list and a pattern (x: xs), if the list is non-empty, then x is bound
   to its head, and xs to its tail.
        Then each guard (if any) associated with that pattern is
        evaluated in turn, with those bindings in effect, until a guard
        succeeds.
        Once a guard succeeds, its RHS is used as the result, with the
        bindings from that pattern still in effect.
        If the pattern match fails, or no guard succeeds, we fall
        through to the next pattern and its guards.

   Note: If all patterns and guards in a function definition were to fail
   on some input, we’d get a runtime error. That would be bad.
And speaking of bad. . .



   Remember our sumVec function?

   sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s
   sumVec [ ]         []          = []

   What happens if we apply this to lists of different lengths?

       sumVec [1,2,3] [4,5,6,7,8]
And speaking of bad. . .



   Remember our sumVec function?

   sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s
   sumVec [ ]         []          = []

   What happens if we apply this to lists of different lengths?

       sumVec [1,2,3] [4,5,6,7,8]

   So . . . what can we do about that exciting behaviour?
One possible response

   Let’s declare that the sum of two vectors should end when we
   reach the end of the shorter vector.

   sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s
   sumVec what        ever        = []

   Whoa, dude. . . Why does this work?
One possible response

   Let’s declare that the sum of two vectors should end when we
   reach the end of the shorter vector.

   sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s
   sumVec what        ever        = []

   Whoa, dude. . . Why does this work?

       The names “what” and “ever” are patterns.
       However, a plain name (with no constructors in sight) does
       not inspect the structure of its argument.
       So “what” and “ever” will each happily match either an
       empty or a non-empty list.
An aside: strings are lists

   In Haskell, we write characters surrounded by single quotes, and
   strings in double quotes. Strings are lists, so:

        ” abc ”

   is syntactic sugar for

        [ ’ a ’ , ’b ’ , ’c ’ ]

   and hence for

        ’a ’ : ’b ’ : ’c ’ : [ ]

   Functions that can manipulate lists can thus manipulate strings.
   Oh, and escape sequences such as ”rnt” work, too.
We are not limited to one constructor per pattern
   Suppose we want to squish consecutive repeats of an element in a
   list.
   compress ” f o o o b a r r r r r r ”
     == ” f o b a r ”
       >

   We can write a function to do this using an elegant combination of
   pattern matching and guards:

   compress ( x : y        : ys )
       | x == y            =      compress ( y : ys )
       | otherwise         = x : compress ( y : ys )
   compress ys             = ys

   Notice that our pattern matches on two consecutive list
   constructors!
Homework
     Write a function that returns the nth element of a list,
     counting from zero.
     nth 2 ” squeak ”
       == ’ u ’
         >

     Write a function that returns the element immdiately before
     the last element of a list.
     lastButOne [1 ,2 ,3 ,4 ,5]
       == 4
         >

     Write a function that determines whether its input is a
     palindrome.
     isPalindrome ” foobar ”
       == F a l s e
         >
     isPalindrome ” foobarraboof ”
       == True
         >

More Related Content

What's hot

Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Philip Schwarz
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Philip Schwarz
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Philip Schwarz
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance HaskellJohan Tibell
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
goncharenko
 
Haskell for data science
Haskell for data scienceHaskell for data science
Haskell for data science
John Cant
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
Philip Schwarz
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
Philip Schwarz
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Philip Schwarz
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore Haskell
Bryan O'Sullivan
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Philip Schwarz
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
Philip Schwarz
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
DEFUN 2008 - Real World Haskell
DEFUN 2008 - Real World HaskellDEFUN 2008 - Real World Haskell
DEFUN 2008 - Real World Haskell
Bryan O'Sullivan
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
Philip Schwarz
 
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Philip Schwarz
 
Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’ Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’
Philip Schwarz
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
Philip Schwarz
 

What's hot (20)

Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
 
Haskell for data science
Haskell for data scienceHaskell for data science
Haskell for data science
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore Haskell
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 
DEFUN 2008 - Real World Haskell
DEFUN 2008 - Real World HaskellDEFUN 2008 - Real World Haskell
DEFUN 2008 - Real World Haskell
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
 
Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’ Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 

Viewers also liked

Coverage Recognition 1
Coverage Recognition 1Coverage Recognition 1
Coverage Recognition 1Tom Neuman
 
Les tic a l'educació. una nova oportunitat per al canvi
Les tic a l'educació. una nova oportunitat per al canviLes tic a l'educació. una nova oportunitat per al canvi
Les tic a l'educació. una nova oportunitat per al canvi
Gemma Tur
 
Test zagadki zwierzeta
Test zagadki zwierzetaTest zagadki zwierzeta
Test zagadki zwierzetaEwaB
 
Measuring Social Media 20091022
Measuring Social Media 20091022Measuring Social Media 20091022
Measuring Social Media 20091022
tonnitommi
 
TRG – Social Media For Retailers
TRG – Social Media For RetailersTRG – Social Media For Retailers
TRG – Social Media For RetailersJaci Russo
 
Emg pilates
Emg pilatesEmg pilates
Emg pilates
Luciana Guimarães
 
[2009] Fisl10 T Learning
[2009] Fisl10 T Learning[2009] Fisl10 T Learning
[2009] Fisl10 T Learning
UFPE
 
Fulfillment of Interdisciplinary Study
Fulfillment of Interdisciplinary StudyFulfillment of Interdisciplinary Study
Fulfillment of Interdisciplinary Study
AMTR
 
Eportfolios and PLEs in Teacher Education. First results.
Eportfolios and PLEs in Teacher Education. First results.Eportfolios and PLEs in Teacher Education. First results.
Eportfolios and PLEs in Teacher Education. First results.
Gemma Tur
 
Global Climatic Change - Engineers Perspective
Global Climatic Change - Engineers PerspectiveGlobal Climatic Change - Engineers Perspective
Global Climatic Change - Engineers PerspectiveAshok Ghosh
 
Critical Mass Forrester 09: Marketing Vegas in a Recession
Critical Mass Forrester 09: Marketing Vegas in a RecessionCritical Mass Forrester 09: Marketing Vegas in a Recession
Critical Mass Forrester 09: Marketing Vegas in a Recession
Critical Mass
 
Trg B2B and Social Media
Trg B2B and Social MediaTrg B2B and Social Media
Trg B2B and Social MediaJaci Russo
 
Walentynki
WalentynkiWalentynki
Walentynki
EwaB
 
Medical Self-Care Issue # 2 (1977)
Medical Self-Care Issue # 2 (1977)Medical Self-Care Issue # 2 (1977)
Medical Self-Care Issue # 2 (1977)
Gilles Frydman
 
Задача1
Задача1Задача1
Задача1sergeeva
 
Lesson From Butterfly
Lesson From ButterflyLesson From Butterfly
Lesson From Butterflyyasir javed
 
Vic Plant Room Nz Water, Ieq Targets
Vic Plant Room Nz Water, Ieq TargetsVic Plant Room Nz Water, Ieq Targets
Vic Plant Room Nz Water, Ieq Targets
twbishop
 
Melinda: Methods and tools for Web Data Interlinking
Melinda: Methods and tools for Web Data InterlinkingMelinda: Methods and tools for Web Data Interlinking
Melinda: Methods and tools for Web Data Interlinking
François Scharffe
 

Viewers also liked (20)

Coverage Recognition 1
Coverage Recognition 1Coverage Recognition 1
Coverage Recognition 1
 
Les tic a l'educació. una nova oportunitat per al canvi
Les tic a l'educació. una nova oportunitat per al canviLes tic a l'educació. una nova oportunitat per al canvi
Les tic a l'educació. una nova oportunitat per al canvi
 
Test zagadki zwierzeta
Test zagadki zwierzetaTest zagadki zwierzeta
Test zagadki zwierzeta
 
Measuring Social Media 20091022
Measuring Social Media 20091022Measuring Social Media 20091022
Measuring Social Media 20091022
 
TRG – Social Media For Retailers
TRG – Social Media For RetailersTRG – Social Media For Retailers
TRG – Social Media For Retailers
 
Emg pilates
Emg pilatesEmg pilates
Emg pilates
 
[2009] Fisl10 T Learning
[2009] Fisl10 T Learning[2009] Fisl10 T Learning
[2009] Fisl10 T Learning
 
Fulfillment of Interdisciplinary Study
Fulfillment of Interdisciplinary StudyFulfillment of Interdisciplinary Study
Fulfillment of Interdisciplinary Study
 
Eportfolios and PLEs in Teacher Education. First results.
Eportfolios and PLEs in Teacher Education. First results.Eportfolios and PLEs in Teacher Education. First results.
Eportfolios and PLEs in Teacher Education. First results.
 
Global Climatic Change - Engineers Perspective
Global Climatic Change - Engineers PerspectiveGlobal Climatic Change - Engineers Perspective
Global Climatic Change - Engineers Perspective
 
Silver Jewellery
Silver JewellerySilver Jewellery
Silver Jewellery
 
Critical Mass Forrester 09: Marketing Vegas in a Recession
Critical Mass Forrester 09: Marketing Vegas in a RecessionCritical Mass Forrester 09: Marketing Vegas in a Recession
Critical Mass Forrester 09: Marketing Vegas in a Recession
 
Art i dona II
Art i dona IIArt i dona II
Art i dona II
 
Trg B2B and Social Media
Trg B2B and Social MediaTrg B2B and Social Media
Trg B2B and Social Media
 
Walentynki
WalentynkiWalentynki
Walentynki
 
Medical Self-Care Issue # 2 (1977)
Medical Self-Care Issue # 2 (1977)Medical Self-Care Issue # 2 (1977)
Medical Self-Care Issue # 2 (1977)
 
Задача1
Задача1Задача1
Задача1
 
Lesson From Butterfly
Lesson From ButterflyLesson From Butterfly
Lesson From Butterfly
 
Vic Plant Room Nz Water, Ieq Targets
Vic Plant Room Nz Water, Ieq TargetsVic Plant Room Nz Water, Ieq Targets
Vic Plant Room Nz Water, Ieq Targets
 
Melinda: Methods and tools for Web Data Interlinking
Melinda: Methods and tools for Web Data InterlinkingMelinda: Methods and tools for Web Data Interlinking
Melinda: Methods and tools for Web Data Interlinking
 

Similar to Real World Haskell: Lecture 2

Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about lazinessJohan Tibell
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
vsssuresh
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and ScalaFolding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Philip Schwarz
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
Prashant Kalkar
 
Lambda Calculus by Dustin Mulcahey
Lambda Calculus by Dustin Mulcahey Lambda Calculus by Dustin Mulcahey
Lambda Calculus by Dustin Mulcahey
Hakka Labs
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao
 
Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
University of Salerno
 
Understanding the "Chain Rule" for Derivatives by Deriving Your Own Version
Understanding the "Chain Rule" for Derivatives by Deriving Your Own VersionUnderstanding the "Chain Rule" for Derivatives by Deriving Your Own Version
Understanding the "Chain Rule" for Derivatives by Deriving Your Own Version
James Smith
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
Kirill Kozlov
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
MatlabIntro.ppt
MatlabIntro.pptMatlabIntro.ppt
MatlabIntro.ppt
ssuser772830
 
Matlab algebra
Matlab algebraMatlab algebra
Matlab algebra
pramodkumar1804
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
Wim Vanderbauwhede
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
Programming Hp33s talk v3
Programming Hp33s talk v3Programming Hp33s talk v3
Programming Hp33s talk v3
Land Surveyors United Community
 

Similar to Real World Haskell: Lecture 2 (20)

Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about laziness
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and ScalaFolding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Lambda Calculus by Dustin Mulcahey
Lambda Calculus by Dustin Mulcahey Lambda Calculus by Dustin Mulcahey
Lambda Calculus by Dustin Mulcahey
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
I1
I1I1
I1
 
Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
 
Understanding the "Chain Rule" for Derivatives by Deriving Your Own Version
Understanding the "Chain Rule" for Derivatives by Deriving Your Own VersionUnderstanding the "Chain Rule" for Derivatives by Deriving Your Own Version
Understanding the "Chain Rule" for Derivatives by Deriving Your Own Version
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
MatlabIntro.ppt
MatlabIntro.pptMatlabIntro.ppt
MatlabIntro.ppt
 
Matlab intro
Matlab introMatlab intro
Matlab intro
 
MatlabIntro.ppt
MatlabIntro.pptMatlabIntro.ppt
MatlabIntro.ppt
 
MatlabIntro.ppt
MatlabIntro.pptMatlabIntro.ppt
MatlabIntro.ppt
 
MatlabIntro.ppt
MatlabIntro.pptMatlabIntro.ppt
MatlabIntro.ppt
 
Matlab algebra
Matlab algebraMatlab algebra
Matlab algebra
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
Programming Hp33s talk v3
Programming Hp33s talk v3Programming Hp33s talk v3
Programming Hp33s talk v3
 

Recently uploaded

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 

Recently uploaded (20)

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 

Real World Haskell: Lecture 2

  • 1. Real World Haskell: Lecture 2 Bryan O’Sullivan 2009-10-14
  • 2. My homework, using only concepts from last week import Data . L i s t ( i s I n f i x O f ) pattern = ” toast ” f o r m a t number l i n e = show number ++ ” : ” ++ l i n e g r e p number i n p u t = i f null input then [ ] e l s e i f i s I n f i x O f p a t t e r n ( head i n p u t ) then f o r m a t number ( head i n p u t ) : g r e p ( number + 1 ) ( t a i l i n p u t ) else g r e p ( number + 1 ) ( t a i l i n p u t ) grepFromOne i n p u t = u n l i n e s ( g r e p 1 ( l i n e s i n p u t ) ) main = i n t e r a c t grepFromOne
  • 3. Wasn’t Haskell supposed to be “pretty”? That grep function sure didn’t look pretty to me! But what, specifically, is ugly about it? We repeat ourselves, using head and tail twice. There’s a mess of nested if /else badness going on.
  • 4. Lists, revisited There are two ways to construct a list: An empty list [] A non-empty list firstElement : restOfList We refer to [] and : as list constructors, since they construct list values.
  • 5. Lists, constructed Knowing about these constructors, how might we construct a 4-element list?
  • 6. Lists, constructed Knowing about these constructors, how might we construct a 4-element list? 1 : 2 : 3 : 4 : [] The bracketed notation we saw last week is syntactic sugar for the form above. In other words, any time you see this: [1,2,3,4] You can read it as this, and vice versa: 1 : 2 : 3 : 4 : []
  • 7. Lists, misconstrued Beginner mistake alert: A list must end with an empty list. So a construction like this makes no sense: ’a’ : ’b’ : ’c’ How would we fix it up? ’a’ : ’b’ : ’c’ : []
  • 8. Back to our roots Remember the fragment of square root code from last week? oneRoot a b c = (−b + ( b ˆ2 + 4∗ a ∗ c ) ) / ( 2 ∗ a ) If we pass in a value of zero for a, the root is undefined, since we’d be dividing by zero. oneRoot a b c = i f a == 0 then (−b + ( b ˆ2 − 4∗ a ∗ c ) ) / (2∗ a ) e l s e e r r o r ” d i v i d e by z e r o ! ”
  • 9. But... I don’t like that if , because how would we write this using mathematical notation? −b ± (b 2 − 4ac) roots(a, b, c) = if a = 0 2a = undefined otherwise And . . . isn’t Haskell supposed to be mathematically inspired?
  • 10. Introducing guards A guard is a Boolean expression preceded by a vertical bar character. oneRoot a b c | a /= 0 = (−b + ( b ˆ2 − 4∗ a ∗ c ) ) / ( 2 ∗ a ) | o t h e r w i s e = e r r o r ” d i v i d e by z e r o ” Guards are evaluated in top-to-bottom order. For the first one that evaluates to True, the expression on the right of the = sign is used as the result of the function. The name otherwise is simply another name for True.
  • 11. Using guards Here’s a second attempt at our grep function, this time using guarded expressions: g r e p number i n p u t | null input = [] | i s I n f i x O f p a t t e r n ( head i n p u t ) = f o r m a t number ( head i n p u t ) : g r e p ( number + 1 ) ( t a i l i n p u t ) | otherwise = g r e p ( number + 1 ) ( t a i l i n p u t )
  • 12. How did this help? We got rid of the nested if expressions, and our “flatter” code is easier to follow. It’s still fugly and repetitive, though. What about head and tail ?
  • 13. Pattern matching When we construct a list, the Haskell runtime has to remember what constructors we used. It goes a step further, and makes this information available to us. We can examine the structure of a piece of data at runtime using pattern matching.
  • 14. Pattern matching on an empty list What’s the length of an empty list? myLength [ ] = 0 This is a function of one argument. If that argument matches the empty-list constructor, our function returns the value 0.
  • 15. Pattern matching on a non-empty list What’s the length of a non-empty list? myLength ( x : x s ) = 1 + myLength x s If our argument matches the non-empty-list constructor “:”, then: the head of the list is bound to the name x; the tail to xs; and the expression is returned with those bindings.
  • 16. Aaaand it’s over to you Now that we know how pattern matching works, let’s do some super-simple exercises: Write versions of the head and tail functions: head [1 ,2 ,3] == > 1 tail [ ’a’ , ’b’ , ’c ’] == > [ ’b’ , ’c ’] Give your versions different names, or you’ll have a hard time trying them out in ghci.
  • 17. Matching alternative patterns We combine our two pattern matches into one function definition by writing them one after the other: myLength [ ] = 0 myLength ( x : x s ) = 1 + myLength x s As with guards, pattern matching proceeds from top to bottom and stops at the first success. The RHS of the first pattern that succeeds is used as the body of the function.
  • 18. Matching alternative patterns We combine our two pattern matches into one function definition by writing them one after the other: myLength [ ] = 0 myLength ( x : x s ) = 1 + myLength x s As with guards, pattern matching proceeds from top to bottom and stops at the first success. The RHS of the first pattern that succeeds is used as the body of the function. Question: What do you suppose happens if no pattern matches?
  • 19. Over to you, part two And now that we know how to write function definitions that can deal with multiple patterns, another exercise: Write a version of the take function: take 3 [100 ,200 ,300 ,400 ,500] ==> [100 ,200 ,300] take 3 [ ’a’ , ’b ’] ==> [ ’a’ , ’b ’] take 3 [] ==> ???
  • 20. Over to you, part two And now that we know how to write function definitions that can deal with multiple patterns, another exercise: Write a version of the take function: take 3 [100 ,200 ,300 ,400 ,500] ==> [100 ,200 ,300] take 3 [ ’a’ , ’b ’] ==> [ ’a’ , ’b ’] take 3 [] ==> ??? Now use ghci to figure out what the drop function does, and write a version of that.
  • 21. Metasyntactic variables Languages have their cultural habits, and Haskell is no exception. You’ll very often see the names used when pattern matching a list follow a naming convention like this: (x: xs) (y: ys) (d:ds) and so on. Think of the “s” suffix as “pluralizing” a name, so “x” (ex) is the head of the list, and “xs” (exes) is the rest.
  • 22. Matching multiple patterns We can match more than one pattern at a time. Consider how we might add the elements of two vectors, represented as lists: sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s sumVec [ ] [] = []
  • 23. Combining pattern matching and guards Things start to get seriously expressive when we combine language features. Remember that bloated grep definition from earlier? Let’s put our new friends to work! grep n [ ] = [] grep n ( x : xs ) | i s I n f i x O f pattern x = format n x : g r e p ( n+1) x s | otherwise = g r e p ( n+1) x s
  • 24. What’s happening here? When we define a function, a pattern binds names to values. Given a list and a pattern (x: xs), if the list is non-empty, then x is bound to its head, and xs to its tail. Then each guard (if any) associated with that pattern is evaluated in turn, with those bindings in effect, until a guard succeeds. Once a guard succeeds, its RHS is used as the result, with the bindings from that pattern still in effect. If the pattern match fails, or no guard succeeds, we fall through to the next pattern and its guards.
  • 25. What’s happening here? When we define a function, a pattern binds names to values. Given a list and a pattern (x: xs), if the list is non-empty, then x is bound to its head, and xs to its tail. Then each guard (if any) associated with that pattern is evaluated in turn, with those bindings in effect, until a guard succeeds. Once a guard succeeds, its RHS is used as the result, with the bindings from that pattern still in effect. If the pattern match fails, or no guard succeeds, we fall through to the next pattern and its guards. Note: If all patterns and guards in a function definition were to fail on some input, we’d get a runtime error. That would be bad.
  • 26. And speaking of bad. . . Remember our sumVec function? sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s sumVec [ ] [] = [] What happens if we apply this to lists of different lengths? sumVec [1,2,3] [4,5,6,7,8]
  • 27. And speaking of bad. . . Remember our sumVec function? sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s sumVec [ ] [] = [] What happens if we apply this to lists of different lengths? sumVec [1,2,3] [4,5,6,7,8] So . . . what can we do about that exciting behaviour?
  • 28. One possible response Let’s declare that the sum of two vectors should end when we reach the end of the shorter vector. sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s sumVec what ever = [] Whoa, dude. . . Why does this work?
  • 29. One possible response Let’s declare that the sum of two vectors should end when we reach the end of the shorter vector. sumVec ( x : x s ) ( y : y s ) = x + y : sumVec x s y s sumVec what ever = [] Whoa, dude. . . Why does this work? The names “what” and “ever” are patterns. However, a plain name (with no constructors in sight) does not inspect the structure of its argument. So “what” and “ever” will each happily match either an empty or a non-empty list.
  • 30. An aside: strings are lists In Haskell, we write characters surrounded by single quotes, and strings in double quotes. Strings are lists, so: ” abc ” is syntactic sugar for [ ’ a ’ , ’b ’ , ’c ’ ] and hence for ’a ’ : ’b ’ : ’c ’ : [ ] Functions that can manipulate lists can thus manipulate strings. Oh, and escape sequences such as ”rnt” work, too.
  • 31. We are not limited to one constructor per pattern Suppose we want to squish consecutive repeats of an element in a list. compress ” f o o o b a r r r r r r ” == ” f o b a r ” > We can write a function to do this using an elegant combination of pattern matching and guards: compress ( x : y : ys ) | x == y = compress ( y : ys ) | otherwise = x : compress ( y : ys ) compress ys = ys Notice that our pattern matches on two consecutive list constructors!
  • 32. Homework Write a function that returns the nth element of a list, counting from zero. nth 2 ” squeak ” == ’ u ’ > Write a function that returns the element immdiately before the last element of a list. lastButOne [1 ,2 ,3 ,4 ,5] == 4 > Write a function that determines whether its input is a palindrome. isPalindrome ” foobar ” == F a l s e > isPalindrome ” foobarraboof ” == True >