# Monads explained to my team — Part 3: Creating a monad

Monoid, Endofunctors… Lots of theoretical pieces have been exposed in the 2 previous parts, but it's time to try and practice with Monads.

## Once upon a time, there were boxes

Let's create a box, to store things like numbers.

• The initializer puts the value inside the box
• `Box#value!` unbox the value and gives it back.
``````class Box

def initialize(value)
@value = value
end

def value! = value
end
``````

## This box does not belong to Schrödinger

That looks utterly useless! So let's add a concept: these boxes can be full (with a value), or empty (value being `nil`).

So, what if we want to add 2 to such a boxed number?

• The box is a container
• We have to take its elements (even though there is only one here) and apply our function to add 2
• We put back the element in the box, and then we return it

… and what if the box is empty? Well, we return an empty Box, then!

``````class Box

def initialize(value)
@value = value
end

def value! = value

return self unless value

Box.new(value + x)
end
end

``````

## Making the box content operation-agnostic

The code above is fine, but if we want to do something else than adding numbers, we would have to add methods all over for each operation. We can do better.

Is there a way to extract something from a container, apply a function to it, and put it back? It was the subject of the previous article: let's make it a functor!

``````class Box

def initialize(value)
@value = value
end

def value! = value

def map
return self unless value

Box.new(yield(value))
end
end

Box.new(nil).map { |x| x + 4 } #=> #<Box:0x0000000 @value=nil>
Box.new(130).map { |x| x + 4 } #=> #<Box:0x0000000 @value=134>
``````

## Nested boxes are the worst…

So, with a Box, we can perform actions on the content without any need to trouble ourselves checking for `nil` values where we are not in control!

``````def double(x) = 2 * x

user_count = Box.new(UserCountAPI.call)
#=> #<Box:0x0000000 @value=25>

shoes_count = user_count.map { |x| double(x) }
#=> #<Box:0x0000000 @value=50>
``````

It's cool enough for us to use the `Box` at some different places in the code. But sometimes, it could create unforeseen problems; for an example, when we are unaware that a method already uses a `Box`:

``````def double(x) = Box.new(2 * x)

user_count = Box.new(UserCountAPI.call)
#=> #<Box:0x0000000 @value=25>

shoes_count = user_count.map { |x| double(x) }
#=> #<Box:0x0000000 @value=#<Box:0x0000000 @value=50>>
``````

… a box inside a box? That's a problem!

To avoid such an issue, we would needs to implement a different `#map` method that would flatten the result: `#flat_map`

``````class Box

def initialize(value)
@value = value
end

def value! = value

def map
return self unless value

Box.new(yield(value))
end

def flat_map(&block)
map(&block).flatten
end

def flatten
return self unless value

value
end
end

Box.new(nil).map { |x| x + 4 } #=> #<Box:0x0000000 @value=nil>
Box.new(130).map { |x| x + 4 } #=> #<Box:0x0000000 @value=134>
Box.new(130).flat_map { |x| Box.new(x + 4) } #=> #<Box:0x0000000 @value=134>
``````

And there we have it! A monad is just that:

• a `mappable` `Box`,
• a method (`Box.new`) to put something in the `Box`,
• a `flat_map` method as an extension of the `map` method.

That's a lot of fuss for something quite simple, right?

#### Useless bit of information

• All `Box` instances (that are endofunctors) represent the monoid set
• `#flat_map` is a closure. As per the first article:
``````Box.new(4).flat_map { |x| Box.new(2 * x) } #=> #<Box:0x0000000 @value=8>

# A_THING  COMBINED_WITH  ANOTHER_THING     => ANOTHER_THING
``````
• `Box.new` is the identity element
``````def double(x) = Box.new(2 * x)
content = 4

# == equality assuming we made Box be comparable
Box.new(content).flat_map { |x| double(x) } == double(content)

Box.new(content).flat_map { |x| Box.new(x) } == Box.new(content)
``````
• `#flat_map` is associative
``````def double(x) = Box.new(2 * x)
def triple(x) = Box.new(3 * x)
content = 4

a = Box.new(content).flat_map { |x| double(x) }
.flat_map { |x| triple(x) }

b = Box.new(content).flat_map do |x|
double(x).flat_map { |y| triple(y) }
end

# == equality assuming we made Box be comparable
a == b
``````

## So what's next?

You can see that a monad is not that complicated a concept, even though its usefulness may not be clear right at once.

Don't worry, we'll develop real-ish example in the next article!