[英]What's the difference between C++23's optional::transform and optional::and_then?
C++23 添加了一些關於可選值的“monadic 風格”功能,作為optional<T>
的方法:
optional<T>::and_then()
(並忽略this
的限定符):
template<class F> constexpr auto and_then(F&& f);
如果包含的值存在,則返回調用 f 的結果。 否則,返回返回類型的空值。
optional<T>::transform()
(並忽略this
的限定符):
template<class F> constexpr auto transform(F&& f);
如果
*this
包含一個值,則返回一個std::optional
,它包含對包含的值調用f
的結果。 否則,返回此類類型的空std::optional
。
那么,這兩個函數不是在做同樣的事情嗎?
措辭和不合格的模板對於找出差異並不是很有幫助,但是: transform()
“重新裝箱”為可選,但and_then()
不會,期望 function 返回裝箱值在其自己的。 所以,
transform()
適用於你想使用 function 之類的T2 foo(T1 x)
;and_then()
適用於當您想使用 function 之類的optional<T2> bar(T1 x)
; ...並且my_optional.transform(foo)
和my_optional.and_then(bar)
都將返回類型為optional<T2>
的值。
另請參閱此問題。
and_then
是 monadic bind
aka flatmap
aka >>=
而transform
是函map
。
人們可以用bind
來表示map
,但反過來不行,因為函子不一定是 monad。 當然, std::optional
的特定 monad 可以隨時打開,因此這兩個函數都可以用普通的 pre-C++23 std::optional
API 來表達。因此,為什么 C++ 標准定義這兩個函數的問題是沒有比為什么它定義兩者中的任何一個的問題更好。 也許標准希望獨立地給程序員一個標准的函數接口和一個標准的單子接口。 任何一個界面本身都是有用且重要的。
and_then
只接受類型為T -> std::optional<U>
的函數(而transform
可以自由接受返回任何類型的函數)。
如果你只是用這樣的 function 進行transform
,你將得到一個std::optional<std::optional<U>>
。
and_then
然后將std::optional<std::optional<U>>
展平為std::optional<U>
。
這就是 monad 的全部: transform
composed with a type level flatten
。 想想range<range<U>>
和future<future<U>>
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.