## DEV Community is a community of 750,871 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Daily Challenge #123 - Curry me Softly

Disclaimer: Currying is not exactly what is described below. Stretch your mind!

Currying is a technique named (as is the language Haskell) after the mathematician Haskell Curry which allows a function's arguments to be fed to it through separate instances of running that function.

Challenge
Create a function which accepts a single argument of another function and returns a "curried" version of that function.

For example, take the following function:

```function adder(arg1, arg2) {
return arg1 + arg2;
}
```

This function would normally be invoked like so:

```var example = adder(1,3); // 4
```

A "curried" version of this function could be executed in either of the following ways

```var example = adder(1)(4); // 5
```

OR

```adder(5)
var example2 = adder(6); // 11
```

Your goal is to produce a higher-order function that accepts another function as an argument and returns a "curried" version of that function.

```function adder () {
return [].slice.call(arguments).reduce(function(a,b){
return a + b
},0);
}
```

This "curried" version of the original function should expand its arguments when invoked with arguments. It should allow multiple arguments to be passed into each invocation.

It should execute the original function and then restore that function's original argument-less state when invoked without arguments.

```curryAdder(1);
var example = curryAdder(); // 16
var example2 = curryAdder(); // 3
```

For fun, let's make sure this works with native global functions and methods too! (will involve some context)

```var curryEval = CurryIt(eval);
curryEval("var y = function(){return true}");
curryEval();
y(); // => true
```

Context should be fixed the first time the "curried" function is called after creation.

Happy coding! :)

This challenge comes from SirRodge on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

## Discussion (10) TypeScript

``````"use strict";

function curry<ParameterType, ReturnType>(callable: Function, ...initial: ParameterType[]): Function {
return function(...additional: ParameterType[]): Function | ReturnType {
const parameters: ParameterType[] = [...initial, ...additional];

if (parameters.length >= callable.length) {
return callable(...parameters);
}

return curry(callable, ...parameters);
};
}

function add(x: number, y: number): number {
return x + y;
}

const \$pow = curry<number, number>(Math.pow);

console.log(Math.pow(10, 2));   // 100
console.log(\$pow(10));          // [Function]
console.log(\$pow(10, 2));       // 100
``````

Playground Heiker • Edited on

I don't think this one is going to work with the last `adder` function, the one that uses `reduce`. Not really currying, but, in any case

``````function adder () {
return [].slice.call(arguments).reduce(function(a,b){
return a + b
},0);
}

if (arguments.length > 0) {
var args = [...arguments];
} else {
return ret;
}
}
``````

repl.it/@logycon/Daily-Challenge-123 Heiker • Edited on

I don't know what's going on with those weird `curryAdder` calls.

``````curryAdder(1);
var example = curryAdder(); // 16
``````

It doesn't look like normal currying to me. You're not using the returned curried function (if there is one).

Anyway. Here is mine. Don't judge me.

``````function curry(fn, arity) {
if (arguments.length === 1) {
// you won't tell me? Fine, I'll guess.
arity = fn.length;

if(arity === 0) {
// you are a sneaky one.
// you trying to curry a variadic function?
// hope you know what you're doing.
return curry.bind(null, fn, {last: 0});
}
}

// Gather the relevant arguments.
var rest = Array.prototype.slice.call(arguments, 2);

var arity_satisfied = arity <= rest.length;

// for that edge case. If it is the same you didn't add new arguments.
var called_without arguments = arity.last === rest.length;

if (arity_satisfied || called_without arguments){
return fn.apply(fn, rest);
}

if(typeof arity.last == 'number') {
// state. Remember the arguments count.
arity.last = rest.length;
}

// you can blame `bind` for not taken an array.
var args = [null, fn, arity].concat(rest);

// call `bind` with `args` and give me a function.
return curry.bind.apply(curry, args);
}
``````

Oh and the test. The test was fun. Did you know that the `assert` module on node had a `strict` mode? I didn't.

``````// this is done with mocha
// mocha --ui qunit -r esm test/**/*.test.js

import { strict as t } from 'assert';
import { curry } from '../../src/utils';

suite('# curry');

test('variadic function without arguments list', function() {
return [].slice.call(arguments).reduce(function(a,b){
return a + b
},0);
}

t.equal(typeof curried, 'function', 'curried is a function');

let curried_1 = curried(1)(1,2,3)(2)(2,5);
t.equal(typeof curried_1, 'function', 'still currying');

t.equal(curried_1(), 16, 'stops when no argument is supplied');
});
`````` willsmart

A simple impl in Typescript...

``````function doCurrishSortOfThingToIt(fn: Function) {
const savedArgs: any[] = [];
return curriedFn;

function curriedFn(...newArgs: any[]) {
savedArgs.push(...newArgs);
if (newArgs.length) return curriedFn;

const result = fn.apply(this, savedArgs);
savedArgs.length = 0;
return result;
}
}
``````

Running though the examples...

``````
return [].slice.call(arguments).reduce(function(a,b){
return a + b
},0);
}

console.log(example, example2) // output: 16, 3

var curryEval = doCurrishSortOfThingToIt(eval);
curryEval("var y = function(){return true}");
curryEval();
console.log(y()); // output: true
`````` Jon Bristow

Type erasure sucks. Kotlin doesn't escape from that fact.

``````fun <A, B, C> curry(a: A, f: (A, B) -> C): (B) -> C = { b -> f(a, b) }

fun <A, B> surround(a: A, b: B): String = "\$a\$b\$a"

fun <A, B, C> curryN(a: A, f: (A, Array<B>) -> C): (Array<B>) -> C = { b -> f(a, b) }

fun main() {

val add12 = curry(12) { a, b: Int -> a + b }

fun <T> currySurround7(b: T): String = curry<Int, T, String>(7, ::surround)(b)

println(currySurround7("Some example"))
println(currySurround7(123))

fun <T> currySurroundOther(b: T) = curry<String, T, String>("not as elegant", ::surround)(b)
println(currySurroundOther("Some example"))
println(currySurroundOther(123))

curryN(3) { a, bsInner: Array<Int> -> bsInner.sum().times(a) }(bs.toTypedArray())

}
`````` This really doesn't seem like currying. It seems counter-productive to even call it that because it seems to go exactly against functional programming's principles by relying on mutability.

Anyways, here's my JavaScript solution for this.

``````function CurryIt(f) {
let currentArgs = [];
const curriedF = (...as) => {
if (as.length === 0) {
const v = f(...currentArgs);
currentArgs = [];
return v;
} else {
currentArgs = currentArgs.concat(as);
return curriedF;
}
};

return curriedF;
}
`````` Michael Kohl

Since I know you’re learning F#: you don’t need to define the `add` function.

``````let add10 = (+) 10
``````