Reputation: 5088
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
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
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
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