2

std::transformfrom <algorithm>header适用于范围,它“使”我们能够使用范围作为它们的函子(在范畴论的意义上(¹))。std::transform是基于迭代器的,是的,但std::ranges::views::transform不是,并且它的签名与函数式语言中相应函数的签名非常匹配,以两个参数的不同顺序为模。

当我看到这个问题(并在回答它的过程中)时,我了解到 C++23 引入了std::optional<T>::transform,它std::optional也是一个仿函数。

所有这些消息都让我兴奋不已,但我不禁想到函子是通用的,并且对transform任何函子有一个统一的接口会很好,例如 Haskell 中的情况。

这让我认为std::ranges::views::transform(它已经是一个对象而不是模板函数)可以作为一个自定义点,STL 不仅可以为范围自定义,还可以为std::optionalSTL 中的任何其他仿函数自定义,而程序员可以自定义它用于他们的用户定义的类。

非常相似,C++23 也引入了std::optional<T>::and_then,这基本上是std::optional. 我不知道有任何类似的函数为范围实现单子绑定,但 C++20some_range | std::ranges::views::transform(f) | std::ranges::views::join本质上是some_rangewith的单子绑定f

这让我觉得可能有一些通用接口,命名它mbind,可以选择任何类型。STL 会选择加入,例如,std::optional根据 实现它std::optional<T>::and_then

有没有机会,或者有没有计划有一天该语言会支持这种通用性?


我当然可以看到一些问题。今天std::ranges::views::transform(some_optional, some_func)是无效的,所以一些代码可能通过 SFINAE 依赖它。让它突然工作会破坏代码。


(¹)关于函子这个词,我指的是范畴论中给出的定义(另见this),而不是“已operator()定义的类的对象”的概念;后者在标准中的任何地方都没有定义,甚至在cppreference中也没有提到,而是使用术语FunctionObject来指代

可以在函数调用运算符左侧使用的对象

4

0 回答 0