Logo

Programming-Idioms

# 37 Currying
Transform a function that takes multiple arguments into a function for which some of the arguments are preset.
New implementation

Be concise.

Be useful.

All contributions dictatorially edited by webmasters to match personal tastes.

Please do not paste any copyright violating material.

Please try to avoid dependencies to third-party libraries and frameworks.

Other implementations
(def add5 (partial + 5))
(def rev-key #(update %2 %1 reverse))

(def rev-a (partial rev-key :a))
//function
auto add(int a, int b) -> int {
	return a + b;
}

//curry with std::bind
using namespace std::placeholders;
auto add5 = std::bind(add, _1, 5);

//curry with lambda
auto add5 = [](int x) { return add(x, 5); };

//use
auto result = add5(1);
assert(result == 6);
#include <functional>
// function taking many parameters
int add(int a, int b)
{
    return a + b;
}

// define a new function preseting the first parameter
std::function<int (int)> add_def(int a)
{
    return [a](int b){return add(a, b);};
}

int result = add_def(4)(6);
using System;
Func<A, C> curry<A, B, C>(Func<A, B, C> f, B b) => (A a) => f(a, b);
import std.functional;
int add(int n1, int n2)
{
    return n1 + n2;
}

alias add5 = curry!(add, 5);
curry(f(a, b), a) => (b) => f(a, b);
defmodule Curry do

  def curry(fun) do
    {_, arity} = :erlang.fun_info(fun, :arity)
    curry(fun, arity, [])
  end

  def curry(fun, 0, arguments) do
    apply(fun, Enum.reverse arguments)
  end

  def curry(fun, arity, arguments) do
    fn arg -> curry(fun, arity - 1, [arg | arguments]) end
  end

end
type PayFactory func(Company, *Employee, *Employee) Payroll

type CustomPayFactory func(*Employee) Payroll

func CurryPayFactory(pf PayFactory,company Company, boss *Employee) CustomPayFactory {
	return func(e *Employee) Payroll {
		return pf(company, boss, e)
	}
}
import Data.Ix
curry range
addThem :: Num a => a -> a -> a
addThem = (+)

add5 :: Num a => a -> a
add5 = addThem 5
const curry = (fn, ...initialArgs) => (...args) => fn(...initialArgs, ...args);

const add = (a, b) => a + b;

const add5 = curry(add, 5);

const result = add5(1) // 6
function curry (fn, scope) {
   
    scope = scope || window;
    
    // omit curry function first arguments fn and scope
    var args = Array.prototype.slice.call(arguments, 2);
    
    return function() {
	var trueArgs = args.concat(Array.prototype.slice.call(arguments, 0));
        fn.apply(scope, trueArgs);
    };
}
import java.util.function.*;
IntBinaryOperator simpleAdd = (a, b) -> a + b;
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(simpleAdd.applyAsInt(4, 5));
System.out.println(curriedAdd.apply(4).applyAsInt(5));
(defun curry (fn &rest args)
  (lambda (&rest remaining-args)
    (apply fn (append args remaining-args))))

(defun add (a b)
  (+ a b))

(funcall (curry add 2) 1) 
  
function curry2(f)
   return function(a)
      return function(b)
         return f(a,b)
      end
   end
end

function add(a,b)
   return a + b
end

local curryAdd = curry2(add)
local add2 = curryAdd(2)
local unpack = unpack or table.unpack
local function aux_ncurry(n, m, fn, args)
  if m>n then return fn(unpack(args,1,n))end
  local new_args, new_m = {}, m
  for i=1,m-1 do new_args[i]=args[i]end
  return function(a) 
    new_args[new_m]=a
    return aux_ncurry(n, new_m + 1, fn, new_args)
  end
end
local function ncurry(n, fn) return aux_ncurry(n,1,fn,{}) end
function curry($f, ...$argsCurried)
{
    return function (...$args) use ($f, $argsCurried) {
        return $f(...$argsCurried, ...$args);
    };
}

function add($n1, $n2)
{
    return $n1 + $n2;
}

$addFive = curry('add', 5);

echo $addFive(2), PHP_EOL;
echo $addFive(-5), PHP_EOL;
function curry($f, ...$argsCurried)
{
    return function (...$args) use ($f, $argsCurried) {
        $finalArgs = array_merge($argsCurried, $args);
        return call_user_func_array($f, $finalArgs);
    };
}

function add($n1, $n2)
{
    return $n1 + $n2;
}

$addFive = curry('add', 5);

echo $addFive(2), PHP_EOL;
echo $addFive(-5), PHP_EOL;
sub curry {
   my ($func, $fixed_arg) = @_;
   return sub {
      $func->($fixed_arg, @_);
   }
}
from functools import partial
def add(a, b):
	return a+b

add_to_two = partial(add, 2)
adder = -> a, b { a + b }
add_two = adder.curry.(2)
add_two.(5) # => 7
fn add(a: u32, b: u32) -> u32 {
    a + b
}

let add5 = move |x| add(5, x);
 
def add(x: Int)(y: Int) = x + y
val add5 = add(5)_
def add(x: Int, y: Int) = x + y
def add5 = add(5, _)
val seven = add5(2)
(define add5 (curry + 5))