3. Higher Order Functions

Created Friday 22 August 2014

Functions as Values

pass3 f = f 3
add1 x = x + 1
pass3 add1

compose f g x = f (g x)
add1 x = x + 1
mult2 x = 2 * x
GHCi> compose add1 mult2 4
Result: 9

always7 x = 7 --compile time
always7' = const 7

Partial Application

foo x y z = x + y + z
foo_1_2 = foo 1 2
GHCi> foo_1_2 3
Result: 6

pass x f = f x
pass3 = pass 3

Operators

GHCi> (+) 5 3
Result: 8

pass_3_4 f = f 3 4
GHCi> pass_3_4 (+)
Result: 7

Operator Definitions

(a,b) .+ (c,d) = (a + c, b + d)

Partially Applying Operators

plus1 = (+) 1 --adds 1 to its argument

plus1' = (1+) --explained in "Map"
plus1'' = (+1)

Turning functions into operators

GHCi> mod 10 2
Result: 0
GHCi> 10 `mod` 2
Result: 0

Map

GHCi> map length ["hello","abc","1234"]
Result: [5,3,4]
GHCi> map (1+) [1,3,5,7]
Result:[2,4,6,8]

double = map (2*)

Filter

notNull xs = not (null xs)
GHCi> filter notNull ["","abc","","hello",""]
Result: ["abc","hello"]

isEven x = x `mod` 2 == 0
removeOdd = filter isEven --function is defined by partially applied filter

GHCi> map snd (filter fst
| (True,1),(False,7),(True,11) |)
Result: [1,11]

Fold

foldl

GHCi> foldl (+) 0 [1,2,3,4]
Result: 10 --0 + 1 + 2 + 3 + 4 = 10

showPlus s x = "(" ++ s ++ "+" ++ (show x) ++ ")" --takes a string and a number
GHCi> showPlus "(1+2)" 3
Result: "((1+2)+3)"

GHCi> foldl showPlus "0" [1,2,3,4]
Result: ((((0+1)+2)+3)+4)

foldr

GHCi> foldr (+) 0 [1,2,3,4]
Result: 10 --1 + 2 + 3 + 4 + 0 = 10

showPlus' x s = "(" ++ (show x) ++ "+" ++ s ++ ")"
GHCi> foldr showPlus' "0" [1,2,3,4]
Result: (1+(2+(3+(4+0))))

foldl vs foldr

GHCi> foldl (-) 0 [1,2,3]
Result: -6
((0-1)-2)-3 = ((-1)-2)-3 = (-3)-3 = -6
GHCi> foldr (-) 0 [1,2,3]
Result: 2
1-(2-(3-0)) = 1-(2-3) = 1-(-1) = 1+1 = 2

Zip

GHCi> zip [1, 2, 3] [4, 5, 6]
Result: [(1,4), (2,5), (3,6)]
GHCi> zip [1, 2] [3, 4, 5, 6]
Result: [(1,3), (2,4)]

zipWith

GHCi> zipWith (+) [1,2,3] [4,5,6]
Result: [5,7,9]

zipWith3

plus3 x y z = x + y + z
GHCi> zipWith3 plus3 [1,2,3] [4,5,6] [7,8,9]
Result: [12,15,18]

zipWith...

Got point...

Lambda Expressions

plus3 x y z = x + y + z
GHCi> zipWith3 (\ x y z -> x + y + z)
[1,2,3] [4,5,6] [7,8,9]
Result: [12,15,18]

GHCi> map (\ x -> 2 * x) [1,2,3]
Result: [2,4,6]
GHCi> map (2*) [1,2,3]
Result: [2,4,6]
GHCi> map (\x -> 2 * x + 1) [1,2,3]
Result: [3,5,7]

When to use Lambda Expressions

Function Operators

Function Composition (.)

stringLength = length . show
GHCi> stringLength 120
Result: 3
stringLength' x = length (show x)

notNull = not . null

f a b = a + b
g x = 2 * x
f . g --error
g . f --error

Function Application ($)

f $ x = f x
f $ g x = f (g x)
f $ g $ h $ k x = f (g (h (k x)))
GHCi> map (\f -> f 3) [(+1), (\x -> 2*x + 3), (*2)]
Result: [4,9,6]
OR
GHCi> map ($3) [(+1), (\x -> 2*x + 3), (*2)]
Result: [4,9,6]

GHCi> zipWith ($) [(+1), (\x -> 2*x + 3), (*2)]
[1,2,3]
Result: [2,7,6]



Backlinks: