A Monad over X simply is a Monoid in the Category of Endofunctors of X.

• Monads are a concept in mathematics
• Algebra is an area of mathematics
• Category theory is an abstraction of algebra.
• Monads are defined in category theory
• Remember: in category theory we talk about infinity beyond cardinality of infinite sets…
• The „idea“ has been transplanted into something used in programming languages…
• Just think of stars in terms of astronomy, in terms of decoration and in terms of music or movies

• Actually Monads should be viewed as a design pattern
• That describes the level of abstraction

# Motivation

• Pure functional programmers are poor guys when it comes to state
• State is evil
• State is not possible or hard
• I/O is state, actually a segment of the outer world is manipulated
• Even if you are happy with state (poor IT theology…):
Multilevel nil problem 🙁

• Container type
• wrap(foo):
• class method
• can also be called unit
• Btw. arrogant Haskell guys call it return
• pass(&block)
• instance method
• Can also be called bind
• Optionally more operations (mjoin, empty, +,…)

```class Identity
def initialize(value)
@value = value
end
end

def Identity.wrap(value)
new(value)
end

class Identity
def pass
yield @value
end
end
```

# Axioms

• Left-identity for pass:
Calling pass on a newly wrapped value is the same as applying the block to that value
• Right-identity for pass:
Calling pass with a block that only calls wrap on its parameter results in the same as its target object
• Nesting:
Nesting pass blocks should be equivalent to calling them in sequence.

# Does our Monad survive 1st law?

```Identity.wrap(foo).pass do |value|
f(value)
end
```

Is equivalent to

```f(foo)
```

That is how we defined pass.

# Does our Monad survive 2nd law?

```bar.pass do |value|
Identity.wrap(value)
end
```

Is equivalent to

```bar
```

That is how we defined pass.

# Does our Monad survive 3rd law?

```bar.pass do |value_a|
f(value_a)
end.pass do |value_b|
g(value_b)
end
```

Is equivalent to

```bar.pass do |value_a|
f(value_a).pass do |value_b|
g(valueb)
end
end
```

That is how we defined pass.

```def Array.wrap(value)
[ value ]
end

class Array
def mjoin
inject([]) { |combined, arr| combined + arr }
end

def pass(&block)
map(&block).mjoin
end
end
```

# Does it work?

Have a look yourself…

Empty:

```def Array::empty
[]
end
```

+:

# Other Examples

• Option (Some, None)