Exagon
Exagon

Reputation: 5088

How to use std::optional in C++

In C++17 std::optional is introduced, I was happy about this decision, until I looked at the ref. I know Optional/Maybe from Scala, Haskell and Java 8, where optional is a monad and follows monadic laws. This is not the case in the C++17 implementation. How am I supposed to use std::optional, whithout functions like map and flatMap/bind, whats the advantage using a std::optional vs for example returning -1, or a nullptr from a function if it fails to compute a result? And more important for me, why wasn't std::optional designed to be a monad, is there a reason?

Upvotes: 10

Views: 5455

Answers (3)

kert
kert

Reputation: 2271

There is P0798r0 proposal with exactly this, and the associated implementation here on Github. The proposal also refers to general monadic interface proposal, and similarly usable std::expected. Implementations of those are also available.

Upvotes: 8

toth
toth

Reputation: 2552

You can define bind and return over std::optional, so in that sense it is still a Monad.

For instance, a possible bind

template<typename T1, typename T2>
std::optional<T2> bind(std::optional<T1> a, std::function< std::optional<T2>(T1)> f) {
   if(a.has_value()) return f(a.value());
   return std::optional<T2>{};
 }

It is actually probably useful to define this.

As to why the standard library does not ship with this, or something like this, I think the answer is one of preferred style in the language.

Upvotes: 4

Guvante
Guvante

Reputation: 19203

How am I supposed to use std::optional, whithout functions like map and flatMap/bind

Maybe in Haskell is perfectly usable without fmap, it represents a value that may or may not be there. It also brings to the type system the distinction so you need to handle both cases.

whats the advantage using a std::optional vs for example returning -1, or a nullptr from a function if it fails to compute a result?

How do you know what the error condition is? Is it 0, -1, MAX_INT, nullptr or something else? If I have both a unsigned int and int return value and the int version previously returned -1 should you change them both to MAX_INT or make them return different values? std::optional avoids the problem.

And more important for me, why wasn't std::optional designed to be a monad, is there a reason?

Does C++ have monads at the moment? Until a different abstraction than the container one there isn't really a way to add that functionality.

Upvotes: 6

Related Questions