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.

Original source

Related problems