Haskell Study Note 8 | Higher-Order Function

Functions as Values

We can use functions as variables, parameters and so on.

An example is (function as values) :

1
2
3
4
5
addOne :: Int -> Int
addOne x = x + 1

f :: Int -> Int
f = addOne

In this case, function f is the same as funtion addone.

Another example (function as parameters) :

1
2
applyTwice :: (Int -> Int) -> Int -> Int
applyTwice f x = f (f x)
  • f here is a parameter
  • This function means use f in x twice

We can use this way to apply :

1
applyTwice (+1) 5

Map

The Basic usage of map :

1
map :: (a -> b) -> [a] -> [b]
  • (a -> b) si a function
  • [a] is the input list
  • [b] is the output list

For example :

1
2
3
map (\s -> s ++ "!") ["hi", "welcome", "to", "Haskell"]

-- output : ["hi!", "welcome!", "to!", "Haskell!"]

Filter

Choose the elements from the list that satisfied out conditions.

Basic usage :

1
filter :: (a -> Bool) -> [a] -> [a]

Such as :

1
2
3
filter even [1, 2, 3, 4, 5, 6]

-- [2, 4, 6]

Choose the string whose length is more than 3

1
filter (\s -> length s > 3) ["cat", "horse", "dog", "elephant"]

Function Composition

compose : .

1
(.) :: (b -> c) -> (a -> b) -> a -> c

which means :

  • First, do the function (a -> b)
  • Then send the output to the left function (b -> c)

For example :

1
2
3
4
5
6
7
8
9
10
double :: Int -> Int
double x = x * 2

addOne :: Int -> Int
addOne x = x + 1

combined :: Int -> Int
combined = addOne . double

-- Input 3 , output 7

which means first double, and then addOne.


We can combine it with map, and that’ s cool :

1
2
3
map (addOne . double) [1, 2, 3]

-- [3, 5, 7]

Lambda Functions

The basic structure :

1
\x -> x + 1

Collocate with map and filter :

1
map (\x -> x * x) [1, 2, 3, 4]
1
filter (\x -> x > 10) [5, 8, 12, 15]

If the parameters are more than 1 :

1
(\x y -> x + y) 3 5

Practice

Consider giving you :

1
2
scores :: [(String, Int)]
scores = [("Alice", 85), ("Bob", 42), ("Charlie", 73), ("Diana", 90), ("Evan", 55)]

We need to finish these tasks :

  1. Find the students whose mark is more than 60
  2. Give every student 5 more scores
  3. Make a new honor list (only reveal name)
1
2
3
4
honorRoll =
map fst
(map (\(name, score) -> (name, score + 5))
(filter (\(_, score) -> score >= 60) scores))