Partial application with a C++ lambda?
c++, c++11, currying, lambda
Solution
A lot of the examples people provided and that i saw elsewhere used helper classes to do whatever they did. I realized this becomes trivial to write when you do that!
#include <utility> // for declval
#include <array>
#include <cstdio>
using namespace std;
template< class F, class Arg >
struct PartialApplication
{
F f;
Arg arg;
constexpr PartialApplication( F&& f, Arg&& arg )
: f(forward<F>(f)), arg(forward<Arg>(arg))
{
}
/*
* The return type of F only gets deduced based on the number of arguments
* supplied. PartialApplication otherwise has no idea whether f takes 1 or 10 args.
*/
template< class ... Args >
constexpr auto operator() ( Args&& ...args )
-> decltype( f(arg,declval<Args>()...) )
{
return f( arg, forward<Args>(args)... );
}
};
template< class F, class A >
constexpr PartialApplication<F,A> partial( F&& f, A&& a )
{
return PartialApplication<F,A>( forward<F>(f), forward<A>(a) );
}
/* Recursively apply for multiple arguments. */
template< class F, class A, class B >
constexpr auto partial( F&& f, A&& a, B&& b )
-> decltype( partial(partial(declval<F>(),declval<A>()),
declval<B>()) )
{
return partial( partial(forward<F>(f),forward<A>(a)), forward<B>(b) );
}
/* Allow n-ary application. */
template< class F, class A, class B, class ...C >
constexpr auto partial( F&& f, A&& a, B&& b, C&& ...c )
-> decltype( partial(partial(declval<F>(),declval<A>()),
declval<B>(),declval<C>()...) )
{
return partial( partial(forward<F>(f),forward<A>(a)),
forward<B>(b), forward<C>(c)... );
}
int times(int x,int y) { return x*y; }
int main()
{
printf( "5 * 2 = %d\n", partial(times,5)(2) );
printf( "5 * 2 = %d\n", partial(times,5,2)() );
}
Problem
EDIT: I use curry below, but have been informed this is instead partial application. I've been trying to figure out how one would write a curry function in C++, and i actually figured it out! ``` #include <stdio.h> #include <functional> template< class Ret, class Arg1, class ...Args > auto curry( Ret f(Arg1,Args...), Arg1 arg ) -> std::function< Ret(Args...) > { return [=]( Args ...args ) { return f( arg, args... ); }; } ``` And i wrote a version for lambdas, too. ``` template< class Ret, class Arg1, class ...Args > auto curry( const std::function<Ret(Arg1,Args...)>& f, Arg1 arg ) -> std::function< Ret(Args...) > { return [=]( Args ...args ) { return f( arg, args... ); }; } ``` The tests: ``` int f( int x, int y ) { return x + y; } int main() { auto f5 = curry( f, 5 ); auto g2 = curry( std::function<int(int,int)>([](int x, int y){ return x*y; }), 2 ); printf("%d\n",f5(3)); printf("%d\n",g2(3)); } ``` Yuck! The line initializing g2 is so large that i might as well have curried it manually. ``` auto g2 = [](int y){ return 2*y; }; ``` Much shorter. But since the intent is to have a really generic and convenient curry function, could i either (1) write a better function or (2) somehow my lambda to implicitly construct an std::function? I fear the current version violates the rule of least surprise when f is not a free function. Especially annoying is how no make_function or similar-type function that i know of seems to exist. Really, my ideal solution would just be a call to std::bind, but i'm not sure how to use it with variadic templates. PS: No boost, please, but i'll settle if nothing else. EDIT: I already know about std::bind. I wouldn't be writing this function if std::bind did exactly what i wanted with the best syntax. This should be more of a special case where it only binds the first element. As i said, my ideal solution should use bind, but if i wanted to use that, i'd use that.