这个元组创建习惯用法有名字吗?

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

相关文章