这个创建元组的习语有名字吗?
在Boost mailinglist上,以下聪明@LouisDionne 最近发布了创建类似元组的实体的技巧:
On the Boost mailinglist, the following clever trick to create a tuple-like entity was recently posted by @LouisDionne:
#include <iostream>
auto list = [](auto ...xs) {
return [=](auto access) { return access(xs...); };
};
auto length = [](auto xs) {
return xs([](auto ...z) { return sizeof...(z); });
};
int main()
{
std::cout << length(list(1, '2', "3")); // 3
}
实例.
聪明之处在于 list
是一个 lambda,它以可变参数列表作为输入,并返回一个 lambda 作为输出,该输出将采用另一个 lambda 对其输入进行操作.类似地,length
是一个 lambda,它采用类似列表的实体,它将向列表的原始输入参数提供可变参数 sizeof...
运算符.sizeof...
操作符被包裹在一个 lambda 中,以便它可以传递给 list
.
The cleverness is that list
is a lambda taking a variadic parameter-list as input, and returning a lambda as an output that will take another lambda to act on its input. Similarly, length
is a lambda taking a list-like entity, to which it will supply the variadic sizeof...
operator to the list's original input parameters. The sizeof...
operator is wrapped inside a lambda so that it can be passed to the list
.
问题:这个创建元组的习语有名字吗?也许来自更常用高阶函数的函数式编程语言.
Question: is there a name for this tuple-creation idiom? Perhaps from a functional programming language where higher-order functions are more commonly used.
推荐答案
我认为这是一个类似 Monad 的东西的微妙实现,特别是与 continuation monad 相同的东西.
I think this is a subtle implementation of a Monad-like thing, specifically something in the same spirit of the continuation monad.
Monad 是一种函数式编程结构,用于模拟计算的不同步骤之间的状态(请记住,函数式语言是无状态的).
monad 所做的是链接不同的函数,创建一个计算管道",其中每个步骤都知道计算的当前状态.
Monads are a functional programming construction used to simulate state between different steps of a computation (Remember that a functional language is stateless).
What a monad does is to chain different functions, creating a "computation pipeline" where each step knows about the current state of the computation.
Monad 有两个主要支柱:
Monads have two primary pilars:
- 一个返回函数,它接受一个值并以 Monad 就绪的形式返回它.
- 一个绑定函数,它采用 Monad-ready 值(来自上一个管道步骤)并将其解包到其原始 from 以将值传递到下一步.
维基百科有关于单子的很好的例子和解释.
The Wikipedia has very good examples and explanations about monads.
让我重写给定的 C++14 代码:
Let me rewrite the given C++14 code:
auto list = []( auto... xs )
{
return [=]( auto access ) { return access(xs...); };
};
我认为这里我们确定了 monad 的 return
函数:获取值并以 Monadic 方式返回它.具体来说,这个返回返回一个从元组"类别到可变参数包类别的函子(在数学意义上,不是 C++ 函子).
I think here we identify the return
function of a monad: Takes the value and returns it in a Monadic way.
Specifically, this return returns a functor (In the mathematical sense, not a C++ functor) which goes from the "tuple" category to the variadic pack category.
auto pack_size = [](auto... xs ) { return sizeof...(xs); };
pack_size
只是一个普通函数.它将在管道中用于完成一些工作.
pack_size
is just a normal function. It would be used in a pipeline to do some work.
auto bind = []( auto xs , auto op )
{
return xs(op);
};
而 length
只是 monad bind
运算符的非泛型版本,该运算符从前一个管道步骤中获取单子值,并绕过它到指定的函数(真正起作用的函数).该函数就是这个计算步骤完成的功能.
And length
is only a non-generic version of something near to the monad bind
operator, an operator which takes a monadic value from a previous pipeline step, and bypasses it to the specified function (Function which really does the work). That function is the functionality done by this computation step.
最后你的调用可以改写为:
Finally your call could be rewritten as:
auto result = bind(list(1,'2',"3"), pack_size);
那么,这个元组创建习语叫什么名字?好吧,我想这可以称为monad-like tuples",因为它不完全是一个 monad,但元组表示和扩展以类似的方式工作,保留到 Haskell 延续 monad.
So, whats the name of this tuple creation idiom? Well, I think this could be called "monad-like tuples", since its not exactly a monad, but the tuple representation and expansion works in a similar way, remaining to the Haskell continuation monad.
只是为了有趣的 C++ 编程,我一直在探索这个类似 monad 的东西.您可以在此处找到一些示例.
Just for the shake of funny C++ programming, I have followed exploring this monad-like thing. You could find some examples here.
相关文章