问题描述
C++23std::optional
终于得到了一些非常有用的附加功能。
因为我对FP的了解非常原始,所以我想知道以下两个操作的语法是什么(根据我的Google搜索是两个基本的一元操作):
- 一元绑定
- 一元回报
我的最佳猜测是:
一元绑定transform
一元返回仅为C++17std::optional
constructor(8)
推荐答案
mbind
(它不存在,我正在模仿哈斯克尔的>>=
)
在类似C++的伪代码中,一元绑定mbind
应该有这样的语法:
C<U> mbind(C<T>, std::function<C<U>(T)>);
即,它应该在某个类型上使用单元格C
,该函数将该单元格的内部拉出,并在不同类型的<[2-8]、C<U>
上转换为单元格,然后返回该单元格。
transform
(空闲的那个)
您提到的transform
首先是一个成员函数,它有这样一个签名类型
C<U> C<T>::transform(std::function<U(T)>);
但让我们重写它的签名,就像它是一个自由函数一样:
C<U> transform(C<T>, std::function<U(T)>);
如您所见,它使用C<T>
并在函数器C
内部应用从T
到U
的函数,从而产生C<U>
。
所以有区别。
若要更好地了解其中的区别,请尝试传递transform
aC<T>
和签名为mbind
的函数std::function<C<U>(T)>
。
你得到了什么?请记住,transform
将函数";直接应用于函数器内部,而不是从函数器中取出任何内容,因此您会得到一个C<C<U>>
,即多一个函数层。
mbind
相反,如果使用相同的两个参数,则会给您一个C<U>
。
transform(x, f)
返回到mbind(x, f)
返回的内容,即从C<C<U>>
到C<U>
?您只需通过join
(在哈斯克尔中称为join
)和flatten
(在其他语言中称为flatten
)来flatten/join/collapse/whatever-you-want-to-name-it这两个功能级别。
显然,如果您可以做到这一点(C = std::optional
也可以),那么这些功能层实际上就是单元层。
那么是否存在类似mbind
的东西?
按照另一个答案中的建议,有and_then
成员函数。
and_then
是我上面提到的(不存在)mbind
吗?可以,它们之间运行的唯一区别是transform
成员函数和transform
自由函数运行的相同:一个是成员函数,另一个是自由函数。
顺便问一下,flatten
/join
在哪里?
您可能想知道C++23中是否有此实用程序。我完全不知道,我几乎不知道C++20提供了什么。
但是,由于使std::optional
成为函数器的函数被定义为std::optional
本身的成员函数,我坚信,如果std::optional
有一元绑定函数,它也会被定义为成员函数,在这种情况下,它将是at this page,在一元运算一节中,与and_then
/transform
/or_else
一起定义。既然没有,我倾向于认为它不存在。
但对Haskell的一些了解可以帮助您了解为什么没有必要将其添加到标准中。
如果执行此操作会发生什么情况?
auto optOfOpt = std::make_optional(std::make_optional(3));
auto whatIsThis = optOfOpt.and_then(std::identity);
对,就是这样。
(≈)本来我比较强调and_then
不是mbind
,因为前者是成员函数,后者是自由函数。
我之所以强调这一点,是因为成员函数属于类(在这样的意义上,如果没有它所属的类,就不能拥有成员函数),因此在某种程度上,我们在这里讨论的and_then
与我们要编写以使std::vector
成为单数的同名函数完全无关,因为它将位于std::vector
内部。
transform
和假设的mbind
是自由函数,因此它们的存在不需要任何类,因此它们看起来更像是类型可以选择加入的一些通用抽象的接口(如Haskell的类型类)。很明显,假设std::transform
和mbind
是定制点,那么想要加入某个类型的客户端代码将必须为该类型编写一个自定义,也许这可以利用一个成员函数。
回答这个问题让我脑海中出现了另一个问题,所以I've asked it。
这篇关于C++23的一元绑定和一元返回是什么可选的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!