Haskell II Functions and patterns 16 Jun21 Data

  • Slides: 32
Download presentation
Haskell II Functions and patterns 16 -Jun-21

Haskell II Functions and patterns 16 -Jun-21

Data Types n n n n Int + - * / ^ even odd

Data Types n n n n Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr is. Space is. Upper … Bool && || not Lists : ++ head tail last init take Tuples fst snd Polymorphic: < <= == /= => > show

User-Defined Data Types n n n User-defined data types data Color = Red |

User-Defined Data Types n n n User-defined data types data Color = Red | Blue to. String Red = "red" to. String Blue = "blue" data Tree a = Leaf a | Branch (Tree a) Can be tricky to use

Assorted Syntax n n n Comments are -- to end of line or {-

Assorted Syntax n n n Comments are -- to end of line or {- to -} (these may be nested) Types are capitalized, variables are not Indentation may be used in place of braces Infix operators: + - `mod` `not` Prefix operators: (+) (-) mod not Types: take : : Int -> [a]

Layout n The first nonblank character following where, let, or of determines the starting

Layout n The first nonblank character following where, let, or of determines the starting column n let x = a + b y=a*b in y / x If you start too far to the left, that may end an enclosing clause You can use { } instead, but this is not usually done

Infinite Lists n n n n [1. . 5] == [1, 2, 3, 4,

Infinite Lists n n n n [1. . 5] == [1, 2, 3, 4, 5] [1. . ] == all positive integers [5, 10. . 32] == [5, 10, 15, 20, 25, 30] [5, 10. . ] == positive multiples of 5 [x*x | x <- [1. . ]] == squares of positive ints [x*x | x <- [1. . ], even x] == squares of positive even ints [(x, y) | x <- [1. . 10], y <- [1. . 10], x < y]

Functions are also data n Functions are “first-class objects” n Functions can be assigned

Functions are also data n Functions are “first-class objects” n Functions can be assigned n Functions can be passed as parameters n Functions can be stored in data structures n There are operations on functions But functions can’t be tested for equality n n Theoretically very hard!

Anonymous Functions n n Form is  parameters -> body Example: x y ->

Anonymous Functions n n Form is parameters -> body Example: x y -> (x + y) / 2 n n n inc x = x + 1 n n the is pronounced “lambda” the x and y are the formal parameters this is shorthand for inc = x -> x + 1 add x y = x + y n this is shorthand for add = x y -> x + y

Currying n n n Technique named after Haskell Curry Functions only need one argument

Currying n n n Technique named after Haskell Curry Functions only need one argument Currying absorbs an argument into a function f a b = (f a) b, where (f a) is a curried function (avg 6) 8 n 7. 0

Slicing n n Functions may be “partially applied” inc x = x + 1

Slicing n n Functions may be “partially applied” inc x = x + 1 n n add x y = x + y n n can be defined instead as inc = (+ 1) can be defined instead as add = (+) negative = (< 0)

map n n n map : : (a -> b) -> [a] -> [b]

map n n n map : : (a -> b) -> [a] -> [b] applies the function to all elements of the list Prelude> map odd [1. . 5] n n [True, False, True] Prelude> map (* 2) [1. . 5] n [2, 4, 6, 8, 10]

filter n n n filter : : (a -> Bool) -> [a] Returns the

filter n n n filter : : (a -> Bool) -> [a] Returns the elements that satisfy the test Prelude> filter even [1. . 10] n n [2, 4, 6, 8, 10] Prelude> filter (x -> x>3 && x<10) [1. . 20] n [4, 5, 6, 7, 8, 9]

iterate n n n iterate : : (a -> a) -> [a] f x

iterate n n n iterate : : (a -> a) -> [a] f x returns the list [x, f f f x, …] Prelude> take 8 (iterate (2 *) 1) n n [1, 2, 4, 8, 16, 32, 64, 128] Prelude> iterate tail [1. . 3] n n [[1, 2, 3], [3], [], *** Exception: Prelude. tail: empty list

foldl n n n foldl : : (a -> b -> a) -> a

foldl n n n foldl : : (a -> b -> a) -> a -> [b] -> a foldl f i x starts with i, repeatedly applies f to i and the next element in the list x Prelude> foldl (-) 100 [1. . 3] n n 94 94 = 100 - 1 - 2 - 3

foldl 1 n n n foldl 1 : : (a -> a) -> [a]

foldl 1 n n n foldl 1 : : (a -> a) -> [a] -> a Same as: foldl f (head x) (tail x) Prelude> foldl 1 (-) [100, 1, 2, 3] n n 94 Prelude> foldl 1 (+) [1. . 100] n 5050

flip n n n flip : : (a -> b -> c) -> b

flip n n n flip : : (a -> b -> c) -> b ->a -> c Reverses first two arguments of a function Prelude> elem 'o' "aeiou" n n Prelude> flip elem "aeiou" 'o' n n True Prelude> (flip elem) "aeiou" 'o' n True

Function composition with (. ) n n (. ) : : (a -> b)

Function composition with (. ) n n (. ) : : (a -> b) -> (c -> a) -> (c -> b) (f. g) x is the same as f (g x) double x = x + x quadruple = double. First = (* 2). head Main> quadruple 3 12 Main> double. First [3. . 10] 6

span n n span : : (a -> Bool) -> [a] -> ([a], [a])

span n n span : : (a -> Bool) -> [a] -> ([a], [a]) Break the lists into two lists n n n Main> span (<= 5) [1. . 10] n n those at the front that satisfy the condition the rest ([1, 2, 3, 4, 5], [6, 7, 8, 9, 10]) Main> span (< 'm') "abracadabra" n ("ab", "racadabra")

break n n break : : (a -> Bool) -> [a] -> ([a], [a])

break n n break : : (a -> Bool) -> [a] -> ([a], [a]) Break the lists into two lists n n n those at the front that fail the condition the rest Main> break (== ' ') "Haskell is neat!" n ("Haskell", " is neat!")

Function Definition I n n Functions are defined with = fact n = if

Function Definition I n n Functions are defined with = fact n = if n == 0 then 1 else n * fact (n - 1)

Function Definition II n n Functions are usually defined by cases fact n |

Function Definition II n n Functions are usually defined by cases fact n | n == 0 =1 | otherwise = n * fact (n - 1) fact n = case n of 0 -> 1 n -> n * fact (n - 1) These are “the same”

Function Definition III n You can separate the cases with “patterns” fact : :

Function Definition III n You can separate the cases with “patterns” fact : : Int -> Int -- not essential n fact 0 = 1 fact n = n * fact (n - 1) How does this work? n

Pattern Matching n n n Functions cannot in general be overloaded But they can

Pattern Matching n n n Functions cannot in general be overloaded But they can be broken into cases Each case must have the same signature fact : : Int -> Int -- explicit signature fact 0 = 1 fact n = n * fact (n - 1) fact 5 won’t match the first, but will match the second

Pattern Types I n n n A variable will match anything A wildcard, _,

Pattern Types I n n n A variable will match anything A wildcard, _, will match anything, but you can’t use the matched value A constant will match only that value Tuples will match tuples, if same length and constituents match Lists will match lists, if same length and constituents match n However, the pattern may specify a list of arbitrary length

Pattern Types II n n n (h: t) will match a nonempty list whose

Pattern Types II n n n (h: t) will match a nonempty list whose head is h and whose tail is t second (h: t) = head t Main> second [1. . 5] n 2

Pattern Types III n n “As-patterns” have the form w@pattern When the pattern matches,

Pattern Types III n n “As-patterns” have the form w@pattern When the pattern matches, the w matches the whole of the thing matched first. Three all@(h: t) = take 3 all Main> first. Three [1. . 10] n [1, 2, 3]

Pattern Types IV n n n (n+k) matches any value equal to or greater

Pattern Types IV n n n (n+k) matches any value equal to or greater than k; n is k less than the value matched silly (n+5) = n Main> silly 20 n 15

Advantages of Haskell n n Extremely concise Easy to understand n n no, really!

Advantages of Haskell n n Extremely concise Easy to understand n n no, really! No core dumps Polymorphism improves chances of re-use Powerful abstractions Built-in memory management

Disadvantages of Haskell n n Unfamiliar Slow n because compromises are less in favor

Disadvantages of Haskell n n Unfamiliar Slow n because compromises are less in favor of the machine

quicksort [] = [] quicksort (x: xs) = quicksort [y | y <- xs,

quicksort [] = [] quicksort (x: xs) = quicksort [y | y <- xs, y < x] ++ [x] ++ quicksort [y | y <- xs, y >= x]

The End

The End