Map, filter, fold
2019-01-18

There are three very commonly used operations in functional programming. Mapping is iterating over elements of a container and applying a function to them. Filtering excludes some elements from the input container. Folding is another name for reducing, and refers to iterating over a container in order to calculate some kind of value.

In Elm, each type of container has to provide its own implementation of these functions, so we have, for example, List.map, Dict.map and Array.map.

map

The map function iterates over every element of the container, returning a new container with the same number of elements:

map : (a -> b) -> List a -> List b

List.map sqrt [2, 3, 5, 7, 11]

-- [1.4142135623730951,1.7320508075688772,2.23606797749979,
-- 2.6457513110645907,3.3166247903554] : List Float

Each element of the input list is passed to the first argument which is a function taking an argument of element type and returning the same or different type.

filter

filter is used to get a subset of elements:

filter : (a -> Bool) -> List a -> List a

List.filter canAddUsers [Engineer, Driver, Foreman, OfficeManager]

-- [Foreman,OfficeManager] : List User

filter returns a list of the same type as the input list, with the same or smaller number of elements.

foldl and foldr

There are two functions able to reduce a container to a single value, which is called folding in Elm. These functions are foldl and foldr:

List.foldl (\a b -> if String.length a > String.length b then a else b) 
    "" ["one", "three", "two", "four"]

-- "three" : String

The difference between them is that foldl iterates over the list from the first element to the last – that is, starting from the left, and foldr iterates in the opposite direction, starting from the end of the list (or the right side):

List.foldl String.append "" ["a", "b", "c"]
-- returns "cba"

List.foldr String.append "" ["a", "b", "c"]
-- returns "abc"

The reason foldl returns “cba” rather than “abc” is that foldl passes each element as the first argument to append, so we’re effectively prepending rather than appending:

foldl : (a -> b -> b) -> b -> List a -> b

Want to learn more about programming in Elm?

If you’d like to go beyond Elm basics, and feel as confident writing Elm as you are with your current language, check out my book, Practical Elm. It will help you learn how to deal with practical tasks that come up when writing real world applications — the kind that you’d put into production at work.

Would you like to dive further into Elm?
📢 My book
Practical Elm
skips the basics and gets straight into the nuts-and-bolts of building non-trivial apps.
🛠 Things like building out the UI, communicating with servers, parsing JSON, structuring the application as it grows, testing, and so on.
Practical Elm