☕ biscuits in teaProgrammingWhy Functions Are Values↑ Top
Haskell · Programming

Why Functions Are Values

The first great Haskell idea: functions can be named, stored, passed around and composed like any other value.

In many languages, a function first appears as a named block of instructions. Haskell invites a more powerful picture: a function is a value. It can be passed to another function, returned as a result and placed inside a data structure.

Higher-order function

A higher-order function accepts another function as an argument, returns one as its result, or does both.

A small transformation

FunctionsAsValues.hs
double :: Int -> Int
double x = x * 2

numbers :: [Int]
numbers = [1, 2, 3, 4]

result :: [Int]
result = map double numbers
map receives the function double as an ordinary argument.

The expression map double numbers does not call double just once. It hands the function itself to map, which applies it to every element.

Anonymous functions

When a transformation is tiny, we can write it directly as a lambda expression.

map (\x -> x * 2) [1, 2, 3, 4]
-- [2, 4, 6, 8]

The backslash resembles the Greek letter λ. Lambda calculus uses λ to mean “construct a function.”

Composition

shout :: String -> String
shout = (++ "!")

announceLength :: String -> String
announceLength = shout . show . length

announceLength "Haskell"
-- "7!"

Composition lets the output of one function become the input of the next. Read shout . show . length from right to left.

Exerciseeasy

Predict the result of map ((+ 1) . (* 2)) [1, 2, 3] before evaluating it.

Reveal solution

Each number is doubled and then incremented, producing [3, 5, 7].