Programming Fundamentals
Lesson 20
Sections
Today, we will…
• Study sections, in Haskell.
• Sections are another class of expressions that
represent functions.
• A section is a binary operation where one of the
operands is missing.
• It represents the unary function in which the
missing operand is the argument, so to speak
• For example, the section (>=10) represents the
function (\x -> x >= 10)
Section examples
• Let’s try some sections at the console:
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 3
Main> (++ " do algarve") "universidade" "universidade do algarve"
Main> (++ " do algarve") "orquestra" "orquestra do algarve"
Main> ("grande " ++) "carro" "grande carro"
Main> ("grande " ++) "festa" "grande festa"
Main> (`mod` 100) 1234 34
Main> (100 `mod`) 32 4
Main> (100 `mod`) 43 14
Main> (`min` 20) 20.3 20.0
Main> (`min` 20) 18.3
Main> (/2) 2891 1445.5
Main> (2/) 2891
0.000691802144586648 Main> (+1) 777
778
Main> (<= 20) 20.3 False
Main> (*10) 64 640
Main> (10^) 6 1000000
Main> (^10) 6 60466176
Main> (1/) 50 0.02
Section examples
• Sections, as lambda expressions, are typically
used as arguments to higher order functions:
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 4
Hugs> map (+1) [5,8,2] [6,9,3]
Hugs> map (*2) [5,8,2] [10,16,4]
Hugs> map (`min` 20) [19.1, 20.4, 21.4, 16.9, 17.7] [19.1,20.0,20.0,16.9,17.7]
Hugs> map (++ ", algarve") ["faro", "tavira", "silves"] ["faro, algarve","tavira, algarve","silves, algarve"] Hugs> filter (<=10) [5,8,12,5,23,44,7,9]
[5,8,5,7,9]
Hugs> filter (/= 0) [0,3,0,1,1,2] [3,1,1,2]
Hugs> map (2^) [0..10]
[1,2,4,8,16,32,64,128,256,512,1024] Hugs> map (1/) (map (2^) [0..10])
[1.0,0.5,0.25,0.125,0.0625,0.03125,0.015625,0.0078125,0.0 0390625,0.001953125,0.0009765625]
Hugs> until (<0.001) (/2) 1 0.0009765625
Quicksort with sections
• Using sections, we can further simplify
quicksort:
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 5
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (x : xs) =
qsort (filter (<= x) xs) ++
[x] ++
qsort (filter (> x) xs)
This is the standard version of quicksort in Haskell.
Remember it, when you have to program quicksort in other languages, in the future.
More exemplary functions
• The most significant digit:
• The last element:
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 6
front :: Int -> Int
front = until (<10) (`div` 10)
This function is defined by a function
expression.
lastElem :: [a] -> a
lastElem = head . until (null . tail) tail
Main> front 374655 3
Main> lastElem [1..512] 512
Functions with multiple
arguments
• Indeed, a function signature such as f :: a -> b -> c must be read as f :: a -> (b -> c).
• Thus, f :: a -> b -> c really means that f is a function with an argument of type a and a result of type (b -> c).
• But (b -> c) is the type of functions with an argument of type b and result of type c.
• This implies that, in this case, an expression f x, where x is an expression of type a, represents a function from b to c.
• We conclude that f is a function with one argument and a function result, and not a function with two arguments.
Examples of function calls with
“missing” arguments
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 8
Hugs> filter (elem 'a') ["faro", "aveiro", "porto"] ["faro","aveiro"]
Main> map (take 2) ["faro", "aveiro", "porto"] ["fa","av","po"]
Main> map (div 100) (map (^2) [1..10]) [100,25,11,6,4,2,2,1,1,1]
map (max 10) [6,9,12,3,45,8] [10,10,12,10,45,10]
Main> map (zip [1..1000]) ["lisboa", "porto"]
[[(1,'l'),(2,'i'),(3,'s'),(4,'b'),(5,'o'),(6,'a')],[ (1,'p'),(2,'o'),(3,'r'),(4,'t'),(5,'o')]]
• Function calls with missing arguments are expressions that represent functions, and can be used as arguments to higher order functions, just like sections:
Note that the missing
IsVowel
• A function to check whether a char is a
owercase vowel:
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 9
isVowel :: Char -> Bool
-- isVowel x = elem x "aeiou"
-- isVowel x = flip elem "aeiou" x -- isVowel x = ((flip elem) "aeiou") x isVowel = flip elem "aeiou"
Main> isVowel 's' False
Main> isVowel 'o' True
Main> filter isVowel "portalegre" "oaee"
Main> filter (not . isVowel) "portalegre" "prtlgr"
Main> filter (not . flip elem "aeiou") "portalegre"
flip' :: (a -> b -> c) -> (b -> a -> c) flip' f x y = f y x
Exercises
• Program a function to remove all vowels from a
string.
• Consider the following two functions:
What does function d compute?
• Program a function compute the length of a list,
based on the idea embodied by functions d and f
above.
23-Jan-11 Programming Fundamentals - 20 © Pedro Guerreiro 10
f :: Integral a => (a, Int) -> (a, Int) f (x, y) = (div x 10, y+1)
d :: Integral a => a -> Int