# Day 98: on fantasy, part 8

*This is part 8 of a series on Implementing a (kinda) fantasy land compliant Maybe type. For part 1, go here, part 2 is here, part 3 can be found here, part 4 here, 5 is here, part 6 is here and the latest part 7 is here*

*The one before the last one*

Today is the day we complete our **Maybe** ðŸŽ‰. And in order to accomplish that, we have to give it 2 more instances:

**Chain****Monad**

And weâ€™ll start with **Chain**.

## Chaining

According to the spec, in order to implement **Chain**, we must also implement **Apply**. Thatâ€™s already done! No, here are the other requirements:

`chain :: Chain m => m a ~> (a -> m b) -> m b`

`m.chain(f)`

This signature is less convoluted than the last one, so letâ€™s try and read it in one go:

Chain is a method on a

`Chain of a`

that takes a function as argument and returns a`Chain of b`

of the same type as that which it was called on.

And, it has some rules:

- The function
`f`

must return a value of the same type as the value that the`chain`

function is called on. `chain`

must return a value of the same type as the value it was called on.

With that in mind, letâ€™s jump to our implementations.

**Nothing** is relatively straightforward. If we look at the signature, we know that the function must return the same type, so it must return a **Maybe**. Since it doesnâ€™t make sense to return a **Just** from a **Nothing** in this case, we are left with just returning **Nothing** like:

```
const Nothing = value => ({
// â€¦
chain: fn => Nothing()
// â€¦
});
```

And, our **Just** implementation can also be built from the type signature. The function that `chain`

takes as an argument must also return a **Maybe**. In that case, we donâ€™t need to wrap the result in the **Just** we already have, so weâ€™re left with an implementation that looks like this:

```
const Just = value => ({
// â€¦
chain: fn => fn(value)
// â€¦
});
```

And thatâ€™s it! Chain has just one law that must be fulfilled, and it looks like this:

`m.chain(f).chain(g)`

is equivalent to`m.chain(x => f(x).chain(g))`

(associativity)

And hereâ€™s how we test it:

```
const chainAssociativity = (f, g, m) =>
m
.chain(f)
.chain(g)
.equals(m.chain(x => f(x).chain(g)));
it("should fulfil the associativity property", () => {
expect(
jsc.checkForall(jsc.fn(maybeArb), jsc.fn(maybeArb), maybeArb, chainAssociativity)
).toBe(true);
});
```

**Chain**âœ…

And now, weâ€™re only left with one algebra to implement: the Monad.

## Monads

This is not a Monad blog post. There are plenty of those around, and to be honest, Iâ€™m not yet qualified to accurately explain or teach Monads. So, letâ€™s just look at what Fantasy Land has to say about them:

A value that implements the Monad specification must also implement the Applicative and Chain specifications.

You know, when I got to this point and read that I assumed there must be something else. Turns out thereâ€™s not. Thatâ€™s it. And in our case, itâ€™s already done since we implemented both **Applicative** and **Chain** before.

We just have to test Monadâ€™s laws to see if we did things right or not:

`M.of(a).chain(f)`

is equivalent to`f(a)`

(left identity)`m.chain(M.of)`

is equivalent to`m`

(right identity)

Hereâ€™s how we test those:

```
const monadLeftIdentity = algebra => (f, a) =>
algebra
.of(a)
.chain(f)
.equals(f(a));
const monadRightIdentity = algebra => (f, m) => m.chain(algebra.of).equals(m);
const maybeMonadLeft = monadLeftIdentity(Maybe);
const maybeMonadRight = monadRightIdentity(Maybe);
describe("Has an instance of Monad which", () => {
it("should fulfil the left identity property", () => {
expect(jsc.checkForall(jsc.fn(maybeArb), jsc.string, maybeMonadLeft)).toBe(true);
});
it("should fulfil the right identity property", () => {
expect(jsc.checkForall(jsc.fn(maybeArb), maybeArb, maybeMonadRight)).toBe(true);
});
});
```

And you know what was great about this? It worked! On the first try! It was very surprising to find out that we had already implemented a **Monad** without writing any more code.

Now, our instance is finally complete:

- Setoid âœ…
- Semigroup âœ…
- Monoid âœ…
- Functor âœ…
- Apply âœ…
- Applicative âœ…
- Foldable âœ…
- Traversable âœ…
- Chain âœ…
- Monad âœ…

And, hereâ€™s a Gist with the completed implementation: https://gist.github.com/ddanielbee/9eb478e93c213db7cabee85c18918747

## Back to the beginning

In part 1 I wrote about the motivation for all of this. It was because Wolfram was curious how **Maybe** code looks, in comparison to **Non-Maybe** code. And Iâ€™ll show you that differenceâ€¦ tomorrow!