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?
The class template std::optional manages an optional contained value, i.e. a value that may or may not be present. A common use case for optional is the return value of a function that may fail.
optional is required to not use dynamic allocation. If an optional contains a value, the value is guaranteed to be allocated as part of the optional object footprint, i.e. no dynamic memory allocation ever takes place.
std::optional Operations If you have existing optional object, then you can easily change the contained value by using several operations like emplace , reset , swap , assign. If you assign (or reset) with a nullopt then if the optional contains a value its destructor will be called.
You can define bind and return over std::optional , so in that sense it is still a Monad.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With