c++monadsmonad-transformersstdoptionalc++23

What's the difference between C++23's optional::transform and optional::and_then?


C++23 adds some "monadic-style" functionality regarding optionals, as methods of optional<T>:

optional<T>::and_then() (and ignoring qualifiers of this):

template<class F> constexpr auto and_then(F&& f); 

Returns the result of invocation of f on the contained value if it exists. Otherwise, returns an empty value of the return type.

optional<T>::transform() (and ignoring qualifiers of this):

template<class F> constexpr auto transform(F&& f);

Returns an std::optional that contains the result of invocation of f on the contained value if *this contains a value. Otherwise, returns an empty std::optional of such type.

So, aren't these two functions doing the same thing?


Solution

  • Suppose you have an optional<T1> value.

    ... and get an optional<T2> at the end. So, transform() will "unbox", apply the function, then "re-box" the function's output into an optional, while and_then() will not do the "re-boxing" at the end, expecting the function to return a boxed value on its own.

    You might also think of transform like std::transform: You apply a function to "each element"; in a container, it may be any number of elements, and in an optional, it's either 0 or 1 elements.

    See also this question.