问题描述
在Boost邮件列表上,以下聪明的@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 将采用另一个 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 的东西的微妙实现,特别是与延续 monad 相同的东西.
I think this is a subtle implementation of a Monad-like thing, specifically something in the same spirit of the continuation monad.
Monads 是一种函数式编程结构,用于模拟计算的不同步骤之间的状态(请记住,函数式语言是无状态的).
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.
Monads 有两个主要支柱:
Monads have two primary pilars:
- 一个返回函数,它接受一个值并以 Monad-ready 的形式返回它.
- 一个绑定函数,它接受一个 Monad-ready 值(来自上一个管道步骤)并将其解包到原始 from 以将该值传递给下一步.
维基百科有关于 monad 的很好的例子和解释.
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
操作符的非通用版本,该操作符从前一个管道步骤中获取一个 monadic 值,并绕过到指定的函数(真正起作用的函数).该函数是此计算步骤完成的功能.
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,但是元组的表示和扩展以类似的方式工作,仍然是 Haskell 的 continuation 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.
这篇关于这个元组创建习惯用法有名字吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!