# What the Functor

Similarly to any complex mathematical concept, it is important to understand the building blocks of the concepts behind the functional programming paradigm.

Disclaimers:

- This post will by no means cover an exhaustive list of FP building blocks.
- The purpose of this post is not to express these concepts with 100% mathematical or grammatical accuracy. The purpose is to build a quick reference to get the point across for my future self 😉
- I will use TypeScript for concrete definitions, Elm for stand-alone type annotations and the Elm REPL for quick expression evaluation.

## Semigroup

Wikipedia's mathematical definition of a **semigroup**:

In mathematics, a semigroup is an algebraic structure consisting of a set together with an associative binary operation.

The binary operation of a semigroup is most often denoted multiplicatively: x·y, or simply xy, denotes the result of applying the semigroup operation to the ordered pair (x, y). Associativity is formally expressed as that (x·y)·z = x·(y·z) for all x, y and z in the semigroup.

In programming, a **semigroup** can be thought of as a structure or data type with an *append* function used to combine elements in the structure. This append function must have the associative property (order of application cannot matter). One could say a list of integers under addition is a semigroup.

Let's explore a practical example using code to make things a bit more clear.

interface Semigroup<T> {concat(x: T, y: T): T;}const everySemigroup: Semigroup<boolean> = {concat: (x, y) => x && y};

You can easily define fold/reduce for a semigroup because you know there is an append function.

const fold = <T>(semigroup: Semigroup<T>,initialValue: T,array: Array<T>): T =>array.reduce(semigroup.concat, initialValue);

Which ultimately makes it easy to construct valuable utilities.

const every =(booleanArray: Array<boolean>): boolean =>fold(everySemigroup, true, booleanArray);

## Monoid

Wikipedia's mathematical definition of a **monoid**:

In abstract algebra, a branch of mathematics, a monoid is an algebraic structure with a single associative binary operation and an identity element. Monoids are semigroups with identity.

That's pretty much it. A **monoid** is a **semigroup** with an *identity value*. Think of an identity value as a neutral element. If you commutatively combine the identity value with an element in your structure it will always return the same element.

**Note:** This is different than the *identity function*.

### Identity Element vs Identity Function

The identity function takes an argument and returns the exact same value that passed to it. The identity function itself *is* a monoid. Check out the following Elm type definition for the identity function.

identity : a -> a

This does a great job of showcasing the power of Elm's type annotations. Any elm function with the signature `a -> a`

is the identity function since `a`

is generic and the only way to ensure you're adhering to the type signature is to conclude that the function will pass back whatever is handed to it.

> identity a = a<function> : a -> a> identity 11 : number> identity "return me""return me" : String> identity [1.1, 2.2][1.1,2.2] : List Float

Here's the TypeScript implementation of the identity function.

const identity = <T>(foo: T) => foo;

While the identity function is an important tool, the identity element is what we're referring to in our definition of a monoid.

- Real numbers under the addition operation have an identity value of
`0`

- Real numbers under multiplication have an identity value of
`1`

- A boolean under the logical
`AND`

operation has an identity value of`true`

- A boolean under the logical
`OR`

operation has an identity value of`false`

All monoids are semigroups, however, not all semigroups are monoids.

## Functor

Wikipedia's mathematical definition of a **functor**:

In mathematics, specifically category theory, a functor is a map between categories.

In FP a functor can be thought of as a collection-like structure with a `map`

operation.

Consider the Elm definition for `List.map`

:

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

In addition to lists, the following are all examples of functors.

- promise
- array
- maybe
- either