News for hackers. Stuff that matters.
Re:Currying by whilenot-dev on Monday April 08, 2024 @06:46AM (#39968344)
Thank you for bringing the topic back on track!

Your example is currying in a manual fashion, so two questions remain for me:

1. How would you tell the compiler to do it for you, as a function transformation?

2. How would you curry a function with 3+ arguments?

Re:Currying by bheadmaster on Monday April 08, 2024 @10:17AM (#39969968)
I can answer both questions with a sprinkle of template magic:

    #include <iostream>
    #include <functional>

    template <typename Ret, typename First, typename ...Rest>
    class Curry {
        std::function<Ret(First, Rest...)> fn;
      public:
        Curry(std::function<Ret(First, Rest...)> fn): fn(fn) {};
        Curry<Ret, Rest...> operator()(First arg) {
            return Curry<Ret, Rest...>{[this, arg](Rest... args) {
                return this->fn(arg, args...);
            }};
        }
    };

    template <typename Ret, typename Arg>
    class Curry<Ret, Arg> {
        std::function<Ret(Arg)> fn;
      public:
        Curry(std::function<Ret(Arg)> fn): fn(fn) {};
        Ret operator()(Arg arg) {
            return this->fn(arg);
        }
    };


    int uncurried(int a, int b, int c) {
        return a + 2*b + 3*c;
    }

    int main() {
        auto curried = Curry<int, int, int, int>{uncurried};

        std::cout << curried(1)(2)(3) << std::endl;
    }
Re:Currying by whilenot-dev on Monday April 08, 2024 @10:58AM (#39970437)
I'm speechless, thank you very much! =)