这个创建元组的习语有名字吗?

在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.

相关文章