Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 827 of the free egghead.io lessons, plus get JavaScript content delivered directly to your inbox!

Existing egghead members will not see this. Sign in.

Just one more step!

Check your inbox for an email from us and click link to unlock your lesson.

Create types with Semigroups

5:52 JavaScript lesson by

An introduction to concatting items via the formal Semi-group interface. Semi-groups are simply a type with a concat method that are associative. We define three semigroup instances and see them in action.

Get the Code Now
click to level up

egghead.io comment guidelines


An introduction to concatting items via the formal Semi-group interface. We define three semigroup instances and see them in action.


Why would we ever use something like First("blah") ?

In reply to egghead.io
Brian Lonsdorf

Here's a "practical" example. The First here always holds an Either.

const First = x =>
  fold: f => x.fold(f, f),
  concat: o => x.isLeft ? o : First(x)

const find = (xs, f) =>
  .foldMap(x => First(f(x) ? Right(x) : Left()), First.empty)
  .fold(x =>x)

In general, the motivation to use semigroups is 4 fold (no pun intended)
1. One has instant intuition that we're doing some kind of combination.
2. There are many properties that hold like identity, associativity, and other group theory stuff.
3. Semigroups beget semigroups... they will combine all the subparts (I show an example in the last real world vid)
4. Since they are associative, they can be parallelized by default.

In reply to Vincent

Let's have a look at semigroups. A semigroup is a type with a concat method. Let's see if we have a string A, we can concat that with the string B. String is the semigroup here because it has a concat method. If we log this out here, we shall see the results AB and there we are.

We can go on concating along because when we concat a string with another string, we will get a string, and so we'll just be able to keep concating along. We say that's closed under concatenation here. It does not change types.

Let's look at another semigroup. We will have one, two. Let's see concat with three, four. We concat that with five, six and so on. Here the array is the semigroup because we have a concat method on the array. If we look at this, we shall have one through six. Very good.

Now, why is it called the semigroup? Why isn't it just called a concatible or something?

That is a good question. The idea is semigroups come from abstract algebra and so we are encoding this in our code so we can keep the name the same and understand the laws and properties that come with this mathematical structure rather than just making something up on our own.

Here we know because of the algebra, we can actually concat the inner part first and then the one, two, and we will get the same results. That property is called associativity. We could do the same with strings because that is also a semigroup.

We can say first concat the B with the C and then we prepend the A instead of what we had earlier which we will concat A with B append the C. This append/prepend grouping doesn't really matter with a semigroup, and that is a great property that holds.

You might remember associativity from addition. If we say 1 + 1 + 1 is the same as 1 + 1 + 1. It does not matter how we group the operations. It will always the same result. That is one property we get from semigroups. Come to think of it addition is a semigroup, but we can't call concat on a number just because it does not have this method it doesn't mean we can't make our own type as we usually do.

Let's go ahead and make a sum semigroup. We will define this any type here, and what we want to write is let's go comment this one up here. We'll say sum of one concat sum of two to get our result of sum three hopefully.

How would we do this? X here is our number so we can say let's make a concat method that takes some other sum function or some type because we're concating at sum one with a sum two, and we will just say we want to return a new sum so we can go on concating. We'll say X plus the other.

This is actually a sum typist, this other sum. We need to expose the X on the type and now we could say o.X. That's because this is a full sum type here so we have to expose this property so we can continue to assert it here.

This should be our results and let's go ahead and run that, and we have X is three. Good. Let's add a little inspect method on our type so we can look at things a little bit easier. We will just put this around here and there we have it. We will have a nice looking sum here. Sum of three, there we go.

I like to destructure this other sum so why don't we say X and we'll assign it to Y, and now we can just say X + Y, much simpler. We are destructuring some type and just grabbing X off of it and calling it a Y here. It should still work, and there we have it.

What are other semigroups? We've defined the sum semigroup so can we define another semigroup? Of course we can. Let's say we have true and false. We shall get false. This is not kind of a concatenation of sort. It combines two things into one thing, and they're both Booleans. How about true and true and we will get true.

Let's go formulize this and make a concat method on a type so that we can capture this conjunction. We'll just copy our template here and actually let's go ahead and copy this bottom part and figure out what are we going to write first here.

We'll say at all. We're going to call this type all because they all have to be true and we'll say true concat all with false should be false, it should be all false. Here we are. Let's go copy our template from the type up here and make ourselves an all.

Our concat shall simply be another all where instead of addition, we will just use conjunction. When we inspect it we see our results and let's go ahead and run this and see what we have. All false, good. If we have all true combined with all true, they are all true. Terrific.

Let's make one more to finish up the semigroup discussion. We want to make a kind of odd one. Let's make one called the first. There's a bit of blur there in the first with ice cream. It will always keep the first one.

How would we do this? Let's go ahead and copy our template. Write first here. If we are to concat our first with another first, we just want to throw it away and keep our first. That would have the effect of just combining things by always keeping the first part of the combination.

Let's go ahead and give this a whirl. Run this over on the right side here and we get first blah, just like what we wanted. It just throws away that and we can keep on concating away and it will always keep the metaprogramming.

It will always keep the first one. There we go. There you have it, semi groups. A type with a concat method that is associative.

Joel's Head
Why are we asking?