// @flow // Type definitions taken from https://github.com/gcanti/flow-static-land/blob/master/src/Fun.js type Fn1 = (a: A, ...rest: Array) => B type Fn2 = (a: A, b: B, ...rest: Array) => C type Fn3 = (a: A, b: B, c: C, ...rest: Array) => D type CurriedFn2 = Fn1> & Fn2 // eslint-disable-next-line no-unused-vars type CurriedFn3 = Fn1> & Fn2> & Fn3 // eslint-disable-next-line no-unused-vars declare function curry(f: Fn2): CurriedFn2 // eslint-disable-next-line no-redeclare declare function curry(f: Fn3): CurriedFn3 function curried(f: Function, length: number, acc: Array): Function { return function fn() { // eslint-disable-next-line prefer-rest-params const combined = acc.concat(Array.prototype.slice.call(arguments)) return combined.length >= length ? f.apply(this, combined) : curried(f, length, combined) } } // eslint-disable-next-line no-redeclare export default function curry(f: Function): Function { // eslint-disable-line no-redeclare return curried(f, f.length, []) }