Download Haskell II - CIS @ UPenn

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Haskell II
Functions and patterns
6-Jul-17
Data Types







Int + - * / ^ even odd
Float + - * / ^ sin cos pi truncate
Char ord chr isSpace isUpper …
Bool && || not
Lists : ++ head tail last init take
Tuples fst snd
Polymorphic:
< <= == /= => > show
User-Defined Data Types





User-defined data types
data Color = Red | Blue
toString Red = "red"
toString Blue = "blue"
data Tree a =
Leaf a | Branch (Tree a) (Tree a)
Can be tricky to use
Assorted Syntax






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] -> [a]
Layout

The first nonblank character following where, let, or
of determines the starting column



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







[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

Functions are “first-class objects”

Functions can be assigned
 Functions can be passed as parameters
 Functions can be stored in data structures
 There are operations on functions
But functions can’t be tested for equality


Theoretically very hard!
Anonymous Functions


Form is \ parameters -> body
Example: \x y -> (x + y) / 2



inc x = x + 1


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

this is shorthand for add = \x y -> x + y
Currying





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

7.0
Slicing


Functions may be “partially applied”
inc x = x + 1


add x y = x + y


can be defined instead as inc = (+ 1)
can be defined instead as add = (+)
negative = (< 0)
map



map :: (a -> b) -> [a] -> [b]
applies the function to all elements of the list
Prelude> map odd [1..5]


[True,False,True,False,True]
Prelude> map (* 2) [1..5]

[2,4,6,8,10]
filter



filter :: (a -> Bool) -> [a] -> [a]
Returns the elements that satisfy the test
Prelude> filter even [1..10]


[2,4,6,8,10]
Prelude> filter (\x -> x>3 && x<10) [1..20]

[4,5,6,7,8,9]
iterate



iterate :: (a -> a) -> a -> [a]
f x returns the list [x, f x, f f x, f f f x, …]
Prelude> take 8 (iterate (2 *) 1)


[1,2,4,8,16,32,64,128]
Prelude> iterate tail [1..3]


[[1,2,3],[2,3],[3],[],
*** Exception: Prelude.tail: empty list
foldl



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]


94
94 = 100 - 1 - 2 - 3
foldl1



foldl1 :: (a -> a -> a) -> [a] -> a
Same as: foldl f (head x) (tail x)
Prelude> foldl1 (-) [100, 1, 2, 3]


94
Prelude> foldl1 (+) [1..100]

5050
flip



flip :: (a -> b -> c) -> b ->a -> c
Reverses first two arguments of a function
Prelude> elem 'o' "aeiou"


Prelude> flip elem "aeiou" 'o'


True
True
Prelude> (flip elem) "aeiou" 'o'

True
Function composition with (.)




(.) :: (a -> b) -> (c -> a) -> (c -> b)
(f . g) x is the same as f (g x)
double x = x + x
quadruple = double . double
doubleFirst = (* 2) . head
Main> quadruple 3
12
Main> doubleFirst [3..10]
6
span


span :: (a -> Bool) -> [a] -> ([a], [a])
Break the lists into two lists



Main> span (<= 5) [1..10]


those at the front that satisfy the condition
the rest
([1,2,3,4,5],[6,7,8,9,10])
Main> span (< 'm') "abracadabra"

("ab","racadabra")
break


break :: (a -> Bool) -> [a] -> ([a], [a])
Break the lists into two lists



those at the front that fail the condition
the rest
Main> break (== ' ') "Haskell is neat!"

("Haskell"," is neat!")
Function Definition I


Functions are defined with =
fact n =
if n == 0 then 1
else n * fact (n - 1)
Function Definition II




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

You can separate the cases with “patterns”
fact :: Int -> Int -- not essential

fact 0 = 1
fact n = n * fact (n - 1)
How does this work?

Pattern Matching





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





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

However, the pattern may specify a list of arbitrary length
Pattern Types II



(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]

2
Pattern Types III




“As-patterns” have the form w@pattern
When the pattern matches, the w matches the whole of
the thing matched
firstThree all@(h:t) = take 3 all
Main> firstThree [1..10]

[1,2,3]
Pattern Types IV



(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


15
This is the only arithmetical pattern; it does not
generalize to any other pattern
Advantages of Haskell


Extremely concise
Easy to understand





no, really!
No core dumps
Polymorphism improves chances of re-use
Powerful abstractions
Built-in memory management
Disadvantages of Haskell


Unfamiliar
Slow

because compromises are less in favor of the machine
quicksort
quicksort [] = []
quicksort (x:xs) =
quicksort [y | y <- xs, y < x] ++
[x] ++
quicksort [y | y <- xs, y >= x]
The End