Skip to content

Commit

Permalink
fix(hof): Rewrite curry from scratch
Browse files Browse the repository at this point in the history
Fixes #350
  • Loading branch information
christopherthielen authored and mergify[bot] committed Dec 27, 2019
1 parent 351b38d commit fc324c6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 12 deletions.
19 changes: 7 additions & 12 deletions src/common/hof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,17 @@ import { Predicate } from './common';
*
* ```
*
* Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function
*
* @param fn
* @returns {*|function(): (*|any)}
*/
export function curry(fn: Function): Function {
const initial_args = [].slice.apply(arguments, [1]);
const func_args_length = fn.length;

function curried(args: any[]) {
if (args.length >= func_args_length) return fn.apply(null, args);
return function() {
return curried(args.concat([].slice.apply(arguments)));
};
}
return curried(initial_args);
return function curried() {
if (arguments.length >= fn.length) {
return fn.apply(this, arguments);
}
const args = Array.prototype.slice.call(arguments);
return curried.bind(this, ...args);
};
}

/**
Expand Down
59 changes: 59 additions & 0 deletions test/hofSpec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { curry } from '../src/common';

describe('curry', () => {
let original: jasmine.Spy;
beforeEach(() => {
original = jasmine.createSpy('original', function(a, b, c) {});
});

it('should accept a function and return a new function', () => {
expect(typeof curry(original)).toBe('function');
});

it('should return a function that invokes original only when all arguments are supplied', () => {
const curried1 = curry(original);
curried1(1, 2, 3);
expect(original).toHaveBeenCalledTimes(1);
expect(original).toHaveBeenCalledWith(1, 2, 3);
});

it('should pass extra arguments through to original function', () => {
const curried1 = curry(original);
curried1(1, 2, 3, 4);
expect(original).toHaveBeenCalledTimes(1);
expect(original).toHaveBeenCalledWith(1, 2, 3, 4);
});

it('should keep returning functions that return functions if no arguments are supplied', () => {
const curried1 = curry(original);
expect(typeof curried1).toBe('function');

const curried2 = curried1();
expect(typeof curried2).toBe('function');

const curried3 = curried2();
expect(typeof curried3).toBe('function');

const curried4 = curried3();
expect(typeof curried4).toBe('function');

const curried5 = curried4();
expect(typeof curried5).toBe('function');

const curried6 = curried5();
expect(typeof curried6).toBe('function');

expect(original).toHaveBeenCalledTimes(0);
});

it('should keep returning functions that return functions until all arguments are supplied', () => {
const curried1 = curry(original);
const curried2 = curried1(1);
const curried3 = curried2(2);
const result = curried3(3);

expect(result).toBeUndefined();
expect(original).toHaveBeenCalledTimes(1);
expect(original).toHaveBeenCalledWith(1, 2, 3);
});
});

0 comments on commit fc324c6

Please sign in to comment.