Disclaimer: Currying is not exactly what is described below. Stretch your mind!
Task
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); } var curryAdder = CurryIt(adder);
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.
See example here, assuming curryAdder from above has been created already:
curryAdder(1); curryAdder(1,2,3); curryAdder(2)(2,5); var example = curryAdder(); // 16 curryAdder(1)(2); 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!
Top comments (9)
TypeScript
Playground
Repl.it.
I don't think this one is going to work with the last
adder
function, the one that usesreduce
.Yes indeed you are correct. My proposal is based on finite arguments. This means that it won't work for an infinite arguments as well as functions that relies on the
arguments
keyword.I don't know what's going on with those weird
curryAdder
calls.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.
Oh and the test. The test was fun. Did you know that the
assert
module on node had astrict
mode? I didn't.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.
A simple impl in Typescript...
Running though the examples...
Not really currying, but, in any case
repl.it/@logycon/Daily-Challenge-123
Type erasure sucks. Kotlin doesn't escape from that fact.
In F#: