💾partial(f, a, b ...)

function composition

JSvaluefunctionhigher-order ⟩ example ⟩ partial(f)

partial application of function

partialLeft(f, a)(x,y) = f(a, x,y)
partialRight(f, a)(x,y) = f(x,y, a)
partial(f, _, a)(x,y) = f(x, a, y)    // _ means `undefined`
// ⭐ partial left
// - partialLeft(f, a,b,c)(x,y) = f(a,b,c, x,y)
//                  ╰───╯           ╰─L─╯
function partialLeft(f, ...outerArgs) {
    return function(...innerArgs) {
        let args = [...outerArgs, ...innerArgs];
        return f.apply(this, args);
    };
}

// ⭐ partial right
// - partialRight(f, a,b,c)(x,y) = f(x,y, a,b,c)
//                   ╰───╯                ╰─R─╯
function partialRight(f, ...outerArgs) {
    return function(...innerArgs) {
        let args = [...innerArgs, ...outerArgs];
        return f.apply(this, args);
    };
}

// ⭐ partial
// - partial(f, a,_,b,_)(x,y,z) = f(a,x,b,y,z)
//              ╰─out─╯  ╰in─╯
function partial(f, ...outerArgs) {
    return function(...innerArgs) {
        
        // copy of outer args
        let args = [...outerArgs]; 
        
        // ⭐ filling in undefined values from inner args
        let innerIndex = 0;
        for (let i = 0; i < args.length; i++) {
            if (args[i] === undefined) args[i] = innerArgs[innerIndex++];
        } 
        
        // append any remaining inner arguments 
        args.push(...innerArgs.slice(innerIndex));
        
        return f.apply(this, args);
    };
}
  • example

const f = (x,y,z) => x * (y - z);    // test function
const _ = undefined;

partialLeft(f, 2)(3,4)    // f(2, 3, 4) = 2 * (3-4) = -2
//             ^               ^
partialRight(f, 2)(3,4)   // f(3, 4, 2) = 3 * (4-2) =  6
//              ^                    ^
partial(f, _, 2)(3,4)     // f(3, 2, 4) = 3 * (2-4) = -6
//            ^                   ^

Last updated