Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
126 views
in Technique[技术] by (71.8m points)

c++ - Is there a name for this tuple-creation idiom?

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    
}

Live Example.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think this is a subtle implementation of a Monad-like thing, specifically something in the same spirit of the continuation 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 have two primary pilars:

  • A return function, which takes a value and returns it in a Monad-ready form.
  • A bind function, which takes a Monad-ready value (From the previous pipeline step) and unwraps it to its original from to pass the value to the next step.

The Wikipedia has very good examples and explanations about monads.

Let me rewrite the given C++14 code:

auto list = []( auto... xs ) 
{ 
    return [=]( auto access ) { return access(xs...); };
};

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 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);
};

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);

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.

Edit: More fun

Just for the shake of funny C++ programming, I have followed exploring this monad-like thing. You could find some examples here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...