54
Functional Programming Pattern Matching H. Turgut Uyar 2013-2015

Functional Programming - Pattern Matching

Embed Size (px)

DESCRIPTION

Tuples, lists, algebraic data types. Pattern matching. Case expressions.

Citation preview

Page 1: Functional Programming - Pattern Matching

Functional ProgrammingPattern Matching

H. Turgut Uyar

2013-2015

Page 2: Functional Programming - Pattern Matching

License

© 2013-2015 H. Turgut Uyar

You are free to:

Share – copy and redistribute the material in any medium or format

Adapt – remix, transform, and build upon the material

Under the following terms:

Attribution – You must give appropriate credit, provide a link to the license, andindicate if changes were made.

NonCommercial – You may not use the material for commercial purposes.

ShareAlike – If you remix, transform, or build upon the material, you mustdistribute your contributions under the same license as the original.

For more information:https://creativecommons.org/licenses/by-nc-sa/4.0/

Read the full license:

https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode

Page 3: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 4: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 5: Functional Programming - Pattern Matching

Tuples

tuple: a combination of a fixed number of values

different but fixed types

n :: (t1, t2, ..., tn)n = (e1, e2, ..., en)

selector functions on pairs:fst, snd

Page 6: Functional Programming - Pattern Matching

Tuple Example

representing a term in a polynomial: 2.4x2

t :: (Float, Integer)t = (2.4, 2)

-- fst t ~> 2.4-- snd t ~> 2

Page 7: Functional Programming - Pattern Matching

Tuple Parameters

tuples can be sent as parameters

not the same as multiple parameters

tuples can be returned as result

Page 8: Functional Programming - Pattern Matching

Tuple Parameter Example

gcd :: Integer -> Integer -> Integergcd x y| y == 0 = x| otherwise = gcd y (x ‘mod‘ y)

gcd’ :: (Integer, Integer) -> Integergcd’ a| snd a == 0 = fst a| otherwise = gcd’ (snd a, (fst a) ‘mod‘ (snd a))

-- gcd 9702 945-- gcd’ (9702, 945)

Page 9: Functional Programming - Pattern Matching

Tuple Result Example

greatest common divisor and least common multiple

gcd_lcm :: Integer -> Integer -> (Integer, Integer)gcd_lcm x y = (d, m)whered = gcd x ym = (x * y) ‘div‘ d

Page 10: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 11: Functional Programming - Pattern Matching

Lists

list: a combination of an arbitrary number of values

all of the same type

n :: [t]n = [e1, e2, ..., en]

Page 12: Functional Programming - Pattern Matching

List Example

representing a polynomial: 2.4x2 + 1.8x − 4.6

-- second degree polynomialp1 :: (Float, Float, Float)p1 = (2.4, 1.8, -4.6)

-- any degree polynomial, coefficients orderedp2 :: [Float]p2 = [2.4, 1.8, -4.6]

-- any degree polynomial, coefficients unorderedp3 :: [(Float, Integer)]p3 = [(1.8, 1), (-4.6, 0), (2.4, 2)]

Page 13: Functional Programming - Pattern Matching

Type Synonyms

type synonym: giving an existing type a new name

type newName = oldName

example: representing a polynomial

type Term = (Float, Integer)type Polynomial = [Term]

p4 :: Polynomialp4 = [(1.8, 1), (-4.6, 0), (2.4, 2)]

Page 14: Functional Programming - Pattern Matching

Type Synonyms

type synonym: giving an existing type a new name

type newName = oldName

example: representing a polynomial

type Term = (Float, Integer)type Polynomial = [Term]

p4 :: Polynomialp4 = [(1.8, 1), (-4.6, 0), (2.4, 2)]

Page 15: Functional Programming - Pattern Matching

Lists

a list consists of a first item (head)followed by a list of the remaining items (tail)

check if empty: null

get the head: head

get the tail: tail

construct a list: item : sublist

independent of type: [a]

Page 16: Functional Programming - Pattern Matching

Lists

a list consists of a first item (head)followed by a list of the remaining items (tail)

check if empty: null

get the head: head

get the tail: tail

construct a list: item : sublist

independent of type: [a]

Page 17: Functional Programming - Pattern Matching

List Operation Examples

null :: [a] -> Bool-- null [] ~> True-- null [1, 2, 3, 4] ~> False

head :: [a] -> a-- head [1, 2, 3, 4] ~> 1-- head [] ~> error-- head [1] ~> 1

tail :: [a] -> [a]-- tail [1, 2, 3, 4] ~> [2, 3, 4]-- tail [] ~> error-- tail [1] ~> []

(:) :: a -> [a] -> [a]-- 1 : [2, 3] ~> [1, 2, 3]

Page 18: Functional Programming - Pattern Matching

List Example

number of elements

length :: [a] -> Intlength xs| null xs = 0| otherwise = 1 + length (tail xs)

Page 19: Functional Programming - Pattern Matching

List Example

number of elements (tail recursive)

length :: [a] -> Intlength xs = lengthIter 0 xswherelengthIter :: Int -> [a] -> IntlengthIter acc xs’| null xs’ = acc| otherwise = lengthIter (acc + 1) (tail xs’)

Page 20: Functional Programming - Pattern Matching

List Example

sum of elements

sum :: [Integer] -> Integersum xs| null xs = 0| otherwise = head xs + sum (tail xs)

Page 21: Functional Programming - Pattern Matching

List Example

sum of first two elements

firstPlusSecond :: [Integer] -> IntegerfirstPlusSecond xs| null xs = 0| null (tail xs) = head xs| otherwise = head xs + head (tail xs)

Page 22: Functional Programming - Pattern Matching

Strings

a string is a list of characters

type String = [Char]

examples

-- head "word" ~> ’w’-- tail "word" ~> "ord"-- null "word" ~> False-- null "" ~> True-- length "word" ~> 4

Page 23: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 24: Functional Programming - Pattern Matching

Algebraic Types

algebraic types: constructors and components

data T = C1 t11 t12 ... t1m |C2 t21 t22 ... t2n |...

value construction: Ci ei1 ei2 ... eik

constructors are functions

Page 25: Functional Programming - Pattern Matching

Algebraic Type Examples

simple product type

type Name = Stringtype Year = Integer

data Human = Person Name Yearderiving Show

church :: Humanchurch = Person "Alonzo Church" 1903

Page 26: Functional Programming - Pattern Matching

Algebraic Type Examples

enumeration

data Month = Jan | Feb | Mar | Apr | May | Jun |Jul | Aug | Sep | Oct | Nov | Decderiving Show

m :: Monthm = Feb

Page 27: Functional Programming - Pattern Matching

Algebraic Type Examples

multiple options

type Coords = (Float, Float)type Length = Float

data Shape = Point Coords |Circle Coords Length |Rectangle Coords Length Lengthderiving Show

p, c, r :: Shapep = Point (0.0, 0.0)c = Circle (0.0, 0.0) 1.0r = Rectangle (45.9, 87.6) 5.75 2.3

Page 28: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 29: Functional Programming - Pattern Matching

Patterns

expressions can be checked against patterns

result is the expression for the first matched pattern

case expr ofp1 -> e1p2 -> e2...pn -> en_ -> e

matched patterns generate bindings

Page 30: Functional Programming - Pattern Matching

Pattern Examples

literal value

gcd :: Integer -> Integer -> Integergcd x y = case y of

0 -> x_ -> gcd y (x ‘mod‘ y)

Page 31: Functional Programming - Pattern Matching

Pattern Examples

tuple matching

gcd’ :: (Integer, Integer) -> Integergcd’ a = case a of

(x, 0) -> x(x, y) -> gcd’ (y, x ‘mod‘ y)

-- gcd’ (9702, 945)-- second pattern, bindings: x <-> 9702, y <-> 945

-- gcd’ (63, 0)-- first pattern, bindings: x <-> 63

Page 32: Functional Programming - Pattern Matching

Nested Patterns

patterns can be nested

example

shift :: ((a, b), c) -> (a, (b, c))shift s = case s of

((x, y), z) -> (x, (y, z))

Page 33: Functional Programming - Pattern Matching

Wildcards

if binding not needed, use wildcard: _

example: third component of a triple

third :: (a, b, c) -> cthird t = case t of

(x, y, z) -> z

-- OR:third t = case t of

(_, _, z) -> z

Page 34: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 35: Functional Programming - Pattern Matching

List Patterns

empty list:[]

nonempty list:x:xs

list with exactly one element:[x]

list with exactly two elements:[x1, x2]

list with at least two elements:x1:x2:xs

Page 36: Functional Programming - Pattern Matching

List Pattern Examples

number of elements

length :: [a] -> Intlength xs = case xs of

[] -> 0x:xs’ -> 1 + length xs’

Page 37: Functional Programming - Pattern Matching

List Pattern Examples

sum of the first and third elements

firstPlusThird :: [Integer] -> IntegerfirstPlusThird xs = case xs of

[] -> 0[x1] -> x1[x1, _] -> x1x1:_:x3:_ -> x1 + x3

Page 38: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 39: Functional Programming - Pattern Matching

Algebraic Type Patterns

patterns can match algebraic types

use pattern matching to get values out of product types

Page 40: Functional Programming - Pattern Matching

Algebraic Type Pattern Examples

get component out of product type

birthYear :: Human -> YearbirthYear p = case p of

Person _ y -> y

-- birthYear (Person "Alonzo Church" 1903) ~> 1903-- binding: y <-> 1903

Page 41: Functional Programming - Pattern Matching

Algebraic Type Pattern Examples

number of days in a month

daysInMonth :: Month -> Integer -> IntegerdaysInMonth m y = case m of

Apr -> 30Jun -> 30Sep -> 30Nov -> 30Feb -> if y ‘mod‘ 4 == 0 then 29 else 28_ -> 31

-- daysInMonth Jan 2014 ~> 31-- daysInMonth Feb 2014 ~> 28-- daysInMonth Feb 2016 ~> 29

Page 42: Functional Programming - Pattern Matching

Algebraic Type Pattern Examples

area of a geometric shape

area :: Shape -> Floatarea s = case s of

Point _ -> 0.0Circle _ r -> 3.14159 * r * rRectangle _ h w -> h * w

-- area (Circle (0.0, 0.0) 3.0) ~> 28.274311-- second pattern, binding: r <-> 3.0

Page 43: Functional Programming - Pattern Matching

Topics

1 Data TypesTuplesListsAlgebraic Types

2 Pattern MatchingPatternsList PatternsAlgebraic Type PatternsFunction Patterns

Page 44: Functional Programming - Pattern Matching

Function Patterns

formal parameters are patterns

components of the pattern will be matchedwith the components of the actual parameters

in case of multiple patterns, the first match will be selected

n p1 = e1n p2 = e2...

Page 45: Functional Programming - Pattern Matching

Function Pattern Example

gcd :: Integer -> Integer -> Integergcd x y = case y of

0 -> x_ -> gcd y (x ‘mod‘ y)

-- OR:gcd :: Integer -> Integer -> Integergcd x 0 = xgcd x y = gcd y (x ‘mod‘ y)

Page 46: Functional Programming - Pattern Matching

Function Pattern Example

gcd’ :: (Integer, Integer) -> Integergcd’ a = case a of

(x, 0) -> x(x, y) -> gcd’ (y, x ‘mod‘ y)

-- OR:gcd’ :: (Integer, Integer) -> Integergcd’ (x, 0) = xgcd’ (x, y) = gcd’ (y, x ‘mod‘ y)

Page 47: Functional Programming - Pattern Matching

Function Pattern Example

shift :: ((a, b), c) -> (a, (b, c))shift s =

case s of((x, y), z) -> (x, (y, z))

-- OR:shift :: ((a, b), c) -> (a, (b, c))shift ((x, y), z) = (x, (y, z))

Page 48: Functional Programming - Pattern Matching

Function Pattern Example

third :: (a, b, c) -> cthird t = case t of

(_ , _, z) -> z

-- OR:third :: (a, b, c) -> cthird (_, _, z) = z

Page 49: Functional Programming - Pattern Matching

Function Pattern Example

length :: [a] -> Intlength xs = case xs of

[] -> 0x:xs’ -> 1 + length xs’

-- OR:length :: [a] -> Intlength [] = 0length (x:xs) = 1 + length xs

Page 50: Functional Programming - Pattern Matching

Function Pattern Example

birthYear :: Human -> YearbirthYear p = case p of

Person _ y -> y

-- OR:birthYear :: Human -> YearbirthYear (Person _ y) = y

Page 51: Functional Programming - Pattern Matching

Example

efficient Fibonacci calculation

fibStep :: (Integer, Integer) -> (Integer, Integer)fibStep (u, v) = (v, u + v)

-- fibPair n ~> (fib n, fib (n + 1))fibPair :: Integer -> (Integer, Integer)fibPair 1 = (1, 1)fibPair n = fibStep (fibPair (n - 1))

fastFib n = fst (fibPair n)

Page 52: Functional Programming - Pattern Matching

Tuples or Algebraic Types?

representing rational numbers

type Rational = (Integer, Integer)

simplify :: Rational -> Rationalsimplify (n, d) = (n ‘div‘ g, d ‘div‘ g)whereg = gcd n d

type DayInYear = (Integer, Integer)

mar12 :: DayInYearmar12 = (12, 3)-- simplify mar12 ~> (4, 1)

Page 53: Functional Programming - Pattern Matching

Tuples or Algebraic Types?

algebraic types give you better type checking

data Rational’ = Fraction Integer Integerderiving Show

simplify’ :: Rational’ -> Rational’simplify’ (Fraction n d) =Fraction (n ‘div‘ g) (d ‘div‘ g)whereg = gcd n d

Page 54: Functional Programming - Pattern Matching

References

Required Reading: ThompsonChapter 5: Data types, tuples and lists