In the previous article "Functional Programming in Go?" we tested the waters to show that some functional programming concepts and Go language could get along.

In this article we will explore a functional programming pattern called *Monad* and one of its canonical implementations - `Option`

type.

As many functional programming concepts, Monads originate from Category theory. And while it's nice to know that a useful development pattern finds its roots in mathematics, we are going to look at this concept from the practical angle only.

Practically, a Monad type is a container type `M`

that wraps some value `A`

and has 2 operations defined: `Unit`

(that wraps a value of type `A`

into a Monad `M`

) and`FlatMap`

(that transforms a wrapped value `A`

to a value `B`

) :

```
type M[A any] struct {
value A
}
func Unit[A any](a A) M[A]
func FlatMap[A, B any](m M[A], f func(a A) M[B]) M[B]
```

It's quite likely that for a person with no prior experience with Monads, this definition would not click right away. To answer a question "but why it is useful?" we will implement a simple but handy `Option`

Monad.

`Option`

type represents some value that might exist or might not. In Go it could be defined using a simple structure like this:

```
type Option[A any] struct {
value A
defined bool
}
```

Also we will define 2 functions for creating an `Option`

. These functions effectively represent `Unit`

operation from the Monad definition above (`Some`

wraps a `value`

into `Option`

, while `None`

represents a lack of value):

```
func Some[A any](value A) Option[A] {
return Option[A]{value, true}
}
func None[A any]() Option[A] {
return Option[A]{defined: false}
}
```

One benefit of using `Option`

type in the code is that it states a developer's intentions clearly. If we see a function returning `Option[string]`

we know that a value might not exist and we are forced to process that case explicitly. We know that if a function returns `string`

then it has to have some meaningful value which we can use in our logic right away, without further checks. But having `Option[string]`

indicates that it might not be the case.

However, even though using our `Option`

type would serve this purpose, it will not be enough to convince how it's better than using another more idiomatic way to handle optional values in Go - returning multiple values like `value, ok = getSomeOptionalValue()`

. But when we complete our `Option`

type implementation by adding a `FlatMap`

operation, it should make some difference. We will define it like that:

```
func FlatMap[A, B any](option Option[A], f func(A) Option[B]) Option[B] {
if option.defined {
return f(option.value)
} else {
return None[B]()
}
}
```

Now imaging we have a chain of computations where each next computation depends on the previous one, but each computation might not return a successful result (a result is optional):

```
func calculate1() Option[int] {
return Some(100)
}
func calculate2(a int) Option[int] {
return Some(a + 200)
}
func calculate3(a int) Option[string] {
return Some(fmt.Sprint(a))
}
func calculate4(a string) Option[string] {
return Some("abc " + fmt.Sprint(a))
}
```

Using our `Option`

Monad we could express the overall computation like that:

```
FlatMap(FlatMap(FlatMap(calculate1(), calculate2), calculate3), calculate4)
// Some(abc 300)
```

And if it happens that any of these computations yields `None`

, then the overall result of the computation would become `None`

as well:

```
FlatMap(FlatMap(FlatMap(None[int](), calculate2), calculate3), calculate4)
// None
```

Essentially, `Option`

Monad could help to chain computations with optional results, thus helping to reduce boilerplate code which is otherwise needed for dealing with non-present values.

#### Conclusion

We've touched slightly a concept of Monads from practical perspective, and implemented a simple `Option`

Monad. Of course, apart from the operations which we defined for `Option`

type, there are many more common functional programming combinators helping to make Options even more useful in practice. If you are interested to find out more or dive deeper into the topic of functional programming in Go, I would be more than happy to see you joining me on GitHub (github.com/ialekseev/go4fun). We can play together :) Thanks for reading!