Home > Enterprise >  What's the difference between C 23's optional::transform and optional::and_then?
What's the difference between C 23's optional::transform and optional::and_then?

Time:11-27

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?

CodePudding user response:

The phrasing, and the unqualified template, aren't super-helpful in figuring out the difference, but: transform() does "re-boxing" into an optional, but and_then() does not, expecting the function to returned a boxed value on its own. So,

  • transform() is for when you want to use a function like T2 foo(T1 x).
  • and_then() is for when you want to use a function like optional<T2> bar(T1 x).

Both my_optional.transform(foo) and my_optional.and_then(bar) return a value of type optional<T2>.

See also this question.

CodePudding user response:

and_then is monadic bind aka flatmap aka >>= and transform is functorial map.

One can express map in terms of bind generically, but not the other way around, because a functor is not necessarily a monad. Of course the particular monad of std::optional can be opened at any time, so both functions are expressible in terms of ordinary pre-C 23 std::optional API. Thus the question why the C standard defines both functions is no better than the question why it defines any of the two. Perhaps the Standard wishes to give the programmer a standard functorial interface and a standard monadic interface independently. Either interface is useful and important on its own right.

  • Related