> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/val/func/kind/higher/partial.md).

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

function composition

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [function](/web/js/val/func.md) ⟩ [higher-order](/web/js/val/func/kind/higher.md) ⟩ example ⟩ partial(f)

{% hint style="success" %}
partial application of function

```javascript
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`
```

{% endhint %}

{% tabs %}
{% tab title="💾 程式" %}

* replit ⟩ [partial(f)](https://replit.com/@pegasusroe/partial#index.js)

```javascript
// ⭐ 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

```javascript
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
//            ^                   ^
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] [JavaScript: The Definitive Guide](/web/master/ref/javascript-the-definitive-guide.md) ⟩ 8.8.2 Higher-Order Functions ⭐️&#x20;
* [ ] Eloquent JavaScript ⟩ [higher-order functions](https://eloquentjavascript.net/05_higher_order.html#h_xxCc98lOBK)
  {% endtab %}
  {% endtabs %}
