Talk:cpp/utility/optional/and then
From cppreference.com
Why do these methods require that the return type is drived from std::optional? It would be far more convenient if the method itself constructed the optional and more in keeping with convenient syntax in other languages such as C#: a?.foo()?.bar()?.baz(). It also requires a default constructible result type, which is another needles(?) restriction.
Never mind - The method I was expecting is called "transform".
[edit] Difference between optional<T>::transform() and optional<T>::and_then()
It is hard to see the difference between optional<T>::transform() and optional<T>::and_then(), so it would be nice if the function description (or an example) would make it clear. --217.229.69.239 08:42, 21 March 2022 (PDT)
- I totally agree. The examples should be more explicit: I think it's
-
std::optional<int>(1).and_then([](auto x) double { return x * 2.5; }) == 2.5
-
std::optional<int>(std::nullopt).and_then([](auto x) double{ return x * 2.5; }) == 0.0
(lambda returns `double` so `and_then` on `nullopt` returns default-constructed `double`). - The other typical-but-interesting case of `and_then`:
-
std::optional<int>(1).and_then([](auto x) -> std::optional<double> { return x * 2.5; }) == std::optional<double>(2.5)
-
std::optional<int>(1).and_then([](auto x) -> std::optional<double> { return x * 2.5; }) == std::optional<double>(std::nullopt)
(lambda returns `std::optional<int>` so `and_then` on `nullopt` returns std::optional<int>(std::nullopt)). -
std::optional<int>(1).transform([](auto x) -> double { return x * 2.5; }) == std::optional<double>(2.5)
-
std::optional<int>(std::nullopt).transform([](auto x) -> double { return x * 2.5; }) == std::optional<double>(std::nullopt)
- Non-typical use of `transform`, where the lambda returns an optional, resulting in nested optionals:
-
std::optional<int>(1).transform([](auto x) -> std::optional<double> { return x * 2.5; }) == std::optional<std::optional<double>>(2.5)
-
std::optional<int>(std::nullopt).transform([](auto x) -> std::optional<double> { return x * 2.5; }) == std::optional<std::optional<double>>(std::nullopt)
-
- Right? BenFrantzDale (talk) 13:45, 28 November 2022 (PST)
- the point of monadic ops (in any language) is to work well in combination: they let us code the happy path and not worry about special cases. So IMO it's important to demonstrate that a) you can process a collection containing a mix of values and nullopts as if nullopts aren't even there and b) you can chain the ops. An example that executes a single op on a single predefined optional doesn't add to what the spec already said. --Cubbi (talk) 06:19, 29 November 2022 (PST)
- (but looking at it now, it will be useful to drop a few more notes on these pages explaining all that, and also that flatmaps avoid nesting.. instead of just mentioning the common names for those with other language experience) --Cubbi (talk) 06:24, 29 November 2022 (PST)