April 24, 2016 / by Kim Hogeling / Web developer / @kimhogeling

### Monoids in F#, JS and PHP

After watching Scott Wlaschin’s talk about functional programming patterns on vimeo I got interested in monoids. But the examples are in F# at which I’m not familiar. Let’s see how they can be used in JavaScript and PHP.

Scott Wlaschin is an IT architect, developer, F# trainer and consultant. He created the website fsharpforfunandprofit.com and is writing a book called understanding functional programming. Mr Wlaschin knows how to explain code design in an easy to follow and enjoyable way. Most of his talks that I have seen are about functional programming, secure code and good code design.

# So, what is a monoid anyway?

You can skip this section, if you watched Scott Wlaschin’s Talk.

The following three rules apply to monoids:

**Closure**:*The result of combining two things is always another one of the things.*This means that the input and output need to be of the same type.**Associativity**:*When combining more than two things, which pairwise combination you do first doesn’t matter.***Identity element**:*There is a special thing called “zero” such that when you combine any thing with “zero” you get the original thing back.*Some examples:`0`

for addition,`1`

for multiplying,`""`

for concatenation

The code in this section is written in JS. The practical example further below is written in F#, JS and PHP.

This is a monoid for numbers because the 3 rules apply:

**Closure**:`add(1, 2)`

equals`3`

**Associativity**:`add(add(1, 2), add(3, 4))`

equals`add(1, add(add(2, 3), 4))`

**Identity element**:`0`

, because`add(0, 1)`

equals`1`

and`add(1, 0)`

also equals`1`

Substract is not a monoid for numbers because 2 out of 3 rules do not apply:

**Closure**:`substract(1, 2)`

equals`-1`

**Associativity**:`substract(substract(1, 2), substract(3, 4))`

does**not**equal`substract(1, substract(substract(2, 3), 4))`

(`0`

does not equal`6`

).**Identity element**: e.g.`0`

is not an identity element, because`substract(0, 1)`

equals`-1`

, but`substract(1, 0)`

does**not**equal`-1`

.

To use the `concatenate`

lambda as a monoid for strings, the list of numbers is first mapped to a list of strings.

Because lambdas are so easy to pass around without any side effects, we can make a list out of them. This list can be mapped to the results of each reduce result for each monoid.

Because `concatenate`

needs different input than numbers, it is not included in this list. Notice, that the values are not passed from lambda to lambda. This is not a chain, but just a simple list. To create a chain the amount of inputs need to match the amount of outputs. That is not the case for our current lambdas, because they accept two arguments and return one value.

# Practical example: Sum of products in a wishlist

Let’s use a more realistic example. Instead of taking Scott Wlaschin’s example, I thought of one, which could be useful for the shopping24 wishlist. This wishlist contains the products that are “starred” by the visitor. I want to sum the prices and shipping costs of the products. This is achieved by combining the wishlist products with help of F# `List.reduce`

, JS `Array.prototype.reduce`

and PHP `array_reduce`

and a monoid called `pairAdd`

.

## F# version

## JS version

## PHP version

I find this solution slick and easy to read. Having `pairAdd`

to be a monoid for any object with the keys `price`

and `shipping`

is simple and doesn’t cause any side effects.

In contrast, the common solution would be to have a Wishlist class which would have a list of products and a method to sum the prices by iterating over the products. But that would create a lot of overhead and would also require noisy variables like `i`

and `length`

.

Anyway, I’m sure I’ll watch more of Scott Wlaschin’s talks. Currently (2016-04-24) Vimeo has 9 uploads of each about an hour. If you care about good code design and security, I recommend Designing with capabilities for fun and profit. So grab some Mate and Nachos and enjoy!