Check out a free preview of the full Hardcore Functional Architecture Patterns in JavaScript course:
The "Monoid Use Cases" Lesson is part of the full, Hardcore Functional Architecture Patterns in JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Brian shares two use cases for monoids to demonstrates how monoids can be used in everyday code and make code cleaner.

Get Unlimited Access Now

Transcript from the "Monoid Use Cases" Lesson

[00:00:00]
>> I wanna show you some examples from a talk I gave that never got recorded. And I think this is kinda cool to see. Instead of me sitting here at a screen and writing all these out, I'm just gonna point out some actual use cases. So here, we have getAppAlerts, right?

[00:00:18] And getDirectMessages. They're both returning the arrays of alerts and messages like JSON. And I can actually just combine all those promises, responses. In a pure functional setting, you'd be using task instead of promise. We can easily write concat on promise by just saying concat whatever this promise is holding with whatever that one's holding.

[00:00:41] And then, we get the ability to combine two API calls and get can collect all their results. We can do that. It's associative, and it's closed, so we can do that in parallel. We can chunk it, we can hit a bunch of servers at once and come back with all the results.

[00:00:55] MapReduce. In the same vein, I didn't mention this earlier, but map is a way to define a semi-group or on a object. And the way it would work is if you look here, we’re gonna go get a post. We did this example on the hardcore functional programming class where we went and got a post from the server, we got it back, and then we got comments from the server and we wanted to assign them to the post.

[00:01:25] Well, this is going that in one line. getPost returns JSON as a map instance, right? So it's like map is an object and it will merge as a concat. And if it hits a merge conflict on a key, it'll just concat the merge conflict. So what you end up having is this kind of map merge situation where we just assigned comments to our blog post just by calling concat.

[00:01:53] Does everybody see how that works? I mean, I'm just kinda gonna glaze over a bunch of these little examples. But it's pretty useful if you ask me and everyone else. So here's a tryCatch. We saw this in the hardcore functional programming class. We're gonna read file sync. This isn't pure, to be fair, but it shows the example of we're gonna say readFileSync.

[00:02:19] And it's gonna just concat all their contents here with the full map. It'll read all these files and concat all the contents, awesome. And if any of them blow up, we will just get the left. I don't have that example. It'll just show you the error. And as we saw before, we can wrap either in another type to kinda gracefully make different decisions.

[00:02:42] So here's the same thing, async, and almost nothing changes, right? We just said promisify the read file, and since we're saying promise here, it has a concat method, it will do the exact same thing, but async. And I changed nothing other than the monoid or semi-group I provided it with.

[00:03:01] And you can see the empty, it's just Promise.resolve empty string. So therefore, we have a monoid in the situation, empty string, and a promise holding empty string would be the empty method of this particular workflow. Here, we have, let's see, read a file and get an array. Works the exact same way as the strings.

[00:03:27] It'll just combine all the arrays. Here's an example of doing a null check. So now, we're cascading these things, right? We're saying okay, I wanna go in there, I wanna read all these files, async. I wanna get all their contents, I wanna split them into words. So we have all these arrays, I'm gonna concat all those arrays.

[00:03:45] But if I get a null, I just wanna stop. [LAUGH] Otherwise, everything worked out and everything's good. That's powerful. This is power. [LAUGH] So let's see couple more examples, and then we'll build some stuff. Here, we have getting a bunch of configs and combining them from files. Here's a good one.

[00:04:14] So this is kind of a typical use case here. So we're gonna do is we're gonna walk over the DOM tree. I made a tree functor slash foldable monoid. And what I've done is say my report is a map, and it's gonna get the element count. And this is playing off the fact that if I'm a type and I'm holding entirely monoids, then I can concat just because all my pieces are also monoids.

[00:04:43] So what map does is just merge, right? And if it hits the same key, it combines those as the merge conflict resolution. So what it's gonna do is run through the entire DOM tree and get every element, every class name, every tag, and max. And each one has a different way to combine, and it will give me an entire report in one loop over the entire tree.

[00:05:05] Which rules [LAUGH], right? I've done this a few different times for DOM tree processing. And if we wanna get super fancy, what if I have a bunch of documents and I wanna fold down that list and get reports on that? There's one extra layer, right? I'm not just doing one DOM tree, I'm doing the entire site now and getting a report on all the elements, classes, tags, and the max height of the bounding regs.

[00:05:32] So that is, again, super powerful.