2:50
JavaScript
lesson by Brian Lonsdorf

We get a clearer definition of what it means to fold a type, then we look at the foldMap function

Now here we have a list of sums, and we want to `concat`

all of these together. We just `reduce`

it down, and `concat`

each one together, starting with the `empty`

value.

```
const { Map, List } = require('immutable-ext')
const { Sum } = require('../monoid')
const res = [Sum(1), Sum(2), Sum(3)]
.reduce((acc, x) => acc.concat(x), Sum.empty())
console.log(res)
```

Now this is a very common operation. We can actually rely on the fact that since there's nothing very special about this function here, it's just calling `concat`

, we could just call `.fold(Sum.empty())`

here, and that would do the exact same thing.

```
const res = [Sum(1), Sum(2), Sum(3)]
.fold(Sum.empty())
//.reduce((acc, x) => acc.concat(x), Sum.empty())
```

We've defined `fold`

knows how to `concat`

all the things together, and then we give it the `empty`

value to start it off. The reason we have to pass this in is because there's no way to know if it's an `empty`

list, where to start, and what to return. We have to give it that.

That's not the case in a typed language, but here in JavaScript, yes, it is. We don't have a `fold`

on the array here, though. No, we have to use a `List`

type here, which has defined `fold`

just like this `reduce`

down here.

Now if we go look at this, we shall get a nice sum of the list. Very good.

```
Sum(6)
```

"Wait. I thought `fold`

took a function."

Ah, yes. `fold`

is a fairly overloaded term. However, it always holds with the same intuition. If we remember `Box`

of whatever we have there, if we `fold`

it down, it will just remove it from the `Box`

. It's just like `map`

, but it will drop down a level.

We did the same, where we have a `Right`

and a `Left`

. We have two handlers here, the error case and success case, but it still removes it from the type.

```
Box(3).fold(x => x) // 3
Right(3).fold(e => e, x => x) // 3
```

Now what about `List`

, though? We have numerous values. We have a collection of things. We need to remove it, but we want to just take one thing out, as such, with the `fold`

. We want to be able to summarize the list, as it were.

Here, with the `fold`

, it is the same intuition, we are just relying on the monoid to be inside the collection so that we can extract one value, in this same `Sum(6)`

. Whenever you see a `fold`

, think removal from a type, be it a collection which relies on a monoid or just a single value in a type.

Let's go ahead and look at a `Map`

here. Let's do the same thing. We'll say `brian`

is `Sum(3)`

, and `sara`

is `Sum(5)`

. We can do the same thing with a `Map`

. It's a collection of things, and it will just sum up the values in the type, extracting it out.

```
const res = Map({brian: Sum(3), sara: Sum(5)})
.fold(Sum.empty())
//.reduce((acc, x) => acc.concat(x), Sum.empty())
```

With a `Map`

here, we don't normally have a monoid in the value slots, or same with lists, we don't typically walk around with lists of sums. How might we put these values into monoids? We can just `map`

over it, and just put each one in a `Sum`

here. If I can just do this first class here. `Sum`

, there we go. If we run this, we get `Sum(8)`

still.

```
const res = Map({brian: Sum(3), sara: Sum(5)})
.map(Sum)
.fold(Sum.empty())
//.reduce((acc, x) => acc.concat(x), Sum.empty())
```

```
Sum(8)
```

If we had a `List.of(1,2,3`

, and we just `map(Sum)`

over those, it will add it together. This mapping, then folding, this put everything into a monoid for us, and then `fold`

it down, is so common, we have a function called `foldMap`

.

```
const res = Map({brian: Sum(3), sara: Sum(5)})
.foldMap(Sum)
.fold(Sum.empty())
//.reduce((acc, x) => acc.concat(x), Sum.empty())
```

This will just take the function to run on each, and then our `empty`

starting value as a second argument here. It's the same as first map, then `fold`

. We have `foldMap`

. Pretty intuitive. If we run this, it should be the `Sum(6)`

still. Very good.

```
const res = Map({brian: Sum(3), sara: Sum(5)})
.foldMap(Sum, Sum.empty())
```

## Comment Guidelines

Member comments are a way for PRO Members to communicate, interact, and ask questions about a lesson.

## Commenting Guidelines

Here are some basic guidelines for commenting on egghead.io.

## Be on-topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact click here.

## Avoid meta-discussion

Is your comment resembles:

It will likely be deleted as "meta".

## Code problem?

Should be accompanied by code! JSFiddle, Plunker, CodePen, etc all provide a way to share code and discuss it in context.

## Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

egghead.io comment guidelines

We get a clearer definition of what it means to fold a type, then we look at the foldMap function

Actually it wasn't clear on the very beginning why this code works:

const res2 = Map({brian: Sum(10), sara: Sum(2)})

.fold(Sum.empty())

but when you look into immutable-ext code

fold : function(empty) {

return this.foldMap(x => x, empty)

},

foldMap : function(f, empty) {

return empty != null

? this.reduce((acc, x) => acc.concat(f(x)), empty)

: this.reduce((acc, x) => acc.concat(f(x)))

},

and then into immutable js docs

reduce(

reducer: (reduction: R, value: V, key: K, iter: Iterable) => R,

initialReduction?: R,

context?: any

): R

Everything become more clearer ;)