npm package: @keepzen/fp
Description: Function Light Programe for nodejs
Author: keep.in.zen@pm.me
Latest version: 1.0.11

![img](//img.shields.io/npm/v/@keepzen/fp.svg)
![img](//img.shields.io/npm/dm/@keepzen/fp.svg)
![img](//img.shields.io/npm/dt/@keepzen/fp.svg)

<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1. id: <code>(any)=&gt;any</code></a></li>
<li><a href="#sec-2">2. unary: <code>(fun)=&gt;Function</code></a></li>
<li><a href="#sec-3">3. binding: <code>(fun,...args)=&gt;Function</code></a></li>
<li><a href="#sec-4">4. compose: <code>(...funs)=&gt;Function</code></a></li>
<li><a href="#sec-5">5. pipe: <code>(...funs)=&gt;Function</code></a></li>
<li><a href="#sec-6">6. m2f: <code>(method)=&gt;Function</code></a></li>
<li><a href="#sec-7">7. deepCopy: <code>(any[,{freeze}])=&gt;any</code></a></li>
<li><a href="#sec-8">8. constant: <code>(any)=&gt;()=&gt;any</code></a></li>
<li><a href="#sec-9">9. Pipable</a></li>
<li><a href="#sec-10">10. not: <code>not(fn)=&gt;Function</code></a></li>
<li><a href="#sec-11">11. selectWith: <code>predicate=&gt;array=&gt;Array</code></a></li>
<li><a href="#sec-12">12. rejectWith: <code>predicate=&gt;array=&gt;Array</code></a></li>
<li><a href="#sec-13">13. orderWith: ~(compare[,{asc}])=&gt;array=&gt;Array</a></li>
<li><a href="#sec-14">14. reverse: <code>(array)=&gt;Array</code></a></li>
<li><a href="#sec-15">15. zip: <code>(aIterable,arrayLikly)=&gt;Array&lt;Array(2)&gt;</code></a></li>
<li><a href="#sec-16">16. every: <code>(fun,iterable)=&gt;boolean</code></a></li>
<li><a href="#sec-17">17. all: <code>(fun,iterable)=&gt;boolean</code></a></li>
<li><a href="#sec-18">18. every: <code>(fun,iterable)=&gt;boolean</code></a></li>
<li><a href="#sec-19">19. any: <code>(fun,iterable)=&gt;boolean</code></a></li>
<li><a href="#sec-20">20. some: <code>(fun,iterable)=&gt;boaolean</code></a></li>
</ul>
</div>
</div>

# id: `(any)=>any`

The idempotent function.

## Parameters

-   `v` **any**

Returns **any** the parameter `v`.

# unary: `(fun)=>Function`

Convert `fun` to an unary function.

## Parameters

-   `fun`

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** 

# binding: `(fun,...args)=>Function`

Biding function `fun` with arguments fellow it.

## Parameters

-   `fun` **Function** This is the function whos parameters you want to bind.
-   `args` &#x2026;\*any\* The values you bind to the parameters of `fun`.

Return Function.

The length of return function is `fun.length - args.length`,
if `args` are all normal values, when `args` includes placeholder `_`,
the length will add the count of placeholders.

## Examples

    const binding = require('./binding');
    const _ = binding.placeHolder;
    const fn = (a, b, c, d) => a + b + c + d;
    test("binding()", () => {
      let bindFn = binding(fn, "1", _, "3");
      expect(typeof bindFn).toBe('function');
      expect(bindFn.length).toBe(fn.length - 2);
      expect(bindFn(2, "a")).toBe('123a');
      let bindFn2 = binding(bindFn, _, "a");
      expect(bindFn2(2)).toBe(bindFn(2, "a"));
      let z = jest.fn(fn);
      let bindFn3 = binding(z, 1, 2, 3, 4, 5);
      expect(bindFn3.length).toBe(0);
      expect(bindFn3()).toBe(1 + 2 + 3 + 4);
      expect(z).toHaveBeenCalledWith(1, 2, 3, 4, 5);
      console.log(bindFn2.toString());
    })

## bindidng.placeHolder: `Symbol`

The place holder that can be use zero or manny times as element of `args` in `binding(fun,...args)`.

# compose: `(...funs)=>Function`

Compose functions `fns` to make a new function.

<div>f &compfn; g = f(g(x))</div>
Read as "f of g" or "f after g".
Means `f` after `g` to run, or `f` is function of value of `g`.

## Parameters

-   `fns` **Function** The functions you want to compose them to be one.

Returns **Function** 

## Examples

    const { compose, pipe } = require('./compose');
    
    const g = jest.fn((a, b) => a + b);
    const f = jest.fn(c => c + 1);
    
    test('compose(f,g)', () => {
      const z = compose(f, g);
      expect(typeof z).toBe('function');
      expect(z.length).toBe(g.length);
      expect(z(1, 2, 3)).toBe(1 + 2 + 1);
      expect(g).toHaveBeenCalledWith(1, 2, 3);
      expect(f).toHaveBeenCalledWith(3);
    })

# pipe: `(...funs)=>Function`

`pipe` is like the `compose` but reverse the execute order.
It is differtne with `pipable`. `pipable` make a functor.

## Parameters

-   `fns` **&#x2026;Function**

Returns **Function** 

## Examples

    const { compose, pipe } = require('./compose');
    
    const g = jest.fn((a, b) => a + b);
    const f = jest.fn(c => c + 1);
    
    test('compose(f,g)', () => {
      const z = compose(f, g);
      expect(typeof z).toBe('function');
      expect(z.length).toBe(g.length);
      expect(z(1, 2, 3)).toBe(1 + 2 + 1);
      expect(g).toHaveBeenCalledWith(1, 2, 3);
      expect(f).toHaveBeenCalledWith(3);
    })
    
    test('pipe(g,f)', () => {
      const z = pipe(g, f);
      expect(typeof z).toBe('function');
      expect(z.length).toBe(g.length);
      expect(z(1, 2, 3)).toBe(1 + 2 + 1);
      expect(g).toHaveBeenCalledWith(1, 2, 3);
      expect(f).toHaveBeenCalledWith(3);
      console.log(z.name);
    })

# m2f: `(method)=>Function`

Convert a method to a function.

If you have a function `fn` you can attch it to a object `obj` like
`obj.fn=fn`, so the `this` in `fn` now is `obj`.

But how do you do if you want use a method as a function?
Like sort arrays with a fixed way?

`m2f` is use to help you for this.

## Parameters

-   `method` **Function** The method you want covert to a function.

Returns **Function**.

The return function do same as `md`, but add `this` as the first parameter.

## Examples

    const m2f = require('./m2f');
    
    test('metholdToFunction()', () => {
      const join = m2f([].join);
      expect(typeof join).toBe(`function`);
      expect(join([1, 2], ",")).toBe([1, 2].join(","));
      expect(join.length).toBe([].join.length + 1);
    })

# deepCopy: `(any[,{freeze}])=>any`

Deep copy the `value`.

## Parameters

-   `v` **any**
-   `$1` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**  (optional, default `{}`)
    -   `$1.freeze`   (optional, default `false`)

Returns a new deep Copyed Object.

## Examples

    const deepCopy = require('./deep-copy');
    
    test('deepCopy()', () => {
      expect(deepCopy(1)).toBe(1);
      expect(deepCopy(true)).toBe(true);
      let fn = jest.fn();
      expect(deepCopy(fn)).toBe(fn);
      let a = [];
      a.push(1, 3);
      a.push(a)
      let aCopy = deepCopy(a);
      expect(aCopy[2]).toBe(aCopy);
      let b = { a, v: 1 };
      a.push(b);
      let bCopy = deepCopy(b);
      console.log(bCopy);
      expect(bCopy === bCopy.a[3]).toBe(true);
    })

# constant: `(any)=>()=>any`

Give a value, get a function, which always return freezen deep copy of 
the given value.

If you just want get a immutable copy, just use
`deepCopy(value,{freeze:true})`.

## Parameters

-   `value` **any**

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** : ()=>freezenDeepCopyOfValue

# Pipable

**Note**:This is the package of `@keepzen/pipe.js`, and in package of `@keepzen/fp` rexport
as `Pipable`. So the snippets in this section, `Pipe`, `pipe`, `from`, and `-` 
are all in namespace of `Pipable`.

## Make a pipable

Pipable is a object, which have a method named `.pipe(fun,...args)`.

You can get a new pipable object as fellow ways:

    const {
      Pipe,
      pipe,
      from,
      _
    } = require('./pipe.js')
    
    test('make pipable', () => {
      const properties = ['valueOf', 'pipe', 'map', "promise_rescue"].sort();
      const keys = Object.keys.bind(Object);
      expect(keys(Pipe(1)).sort()).toMatchObject(properties);
      expect(keys(pipe(1)).sort()).toMatchObject(properties);
      expect(keys(from(1)).sort()).toMatchObject(properties);
      expect(keys(from(1).pipe(a => a + 1)).sort()).toMatchObject(properties);
    })

As then snippet showed, a `pipable` object have methods as fellow:
-   `pipable.valueOf()` : 
    
    Get the `v` you want to pipe to other function.
    
    So `pipe(a).valueOf() === a` is always `true`:

    test('pipe(any).valueOf() == any', () => {
      expect(pipe(1).valueOf() == 1).toBe(true)
      expect(pipe("hello").valueOf() == "hello").toBe(true);
      expect(pipe(true).valueOf() == true).toBe(true);
      expect(pipe(false).valueOf() == false).toBe(true);
      let str = new String('Hello');
      expect(pipe(str).valueOf() == str).toBe(true);
      expect(pipe(null).valueOf() == null).toBe(true);
      expect(pipe(undefined).valueOf() == undefined).toBe(true);
      let a = { hello: "a" };
      expect(pipe(a).valueOf() == a).toBe(true)
    })

</code>

If `a` is primary type but neither `null` nor `undefined` then `pipe(a) == a`
is true.

    test('pipe(primary) == primary', () => {
      expect(pipe(1) == 1).toBe(true)
      expect(pipe("hello") == "hello").toBe(true);
      expect(pipe(true) == true).toBe(true);
      expect(pipe(false) == false).toBe(true);
      let str = new String('Hello')
      expect(pipe(str) == str).toBe(false);
      expect(pipe(null) == null).toBe(false);
      expect(pipe(undefined) == undefined).toBe(false);
      let a = { hello: "a" };
      expect(pipe(a) == a).toBe(false);
    })

-   `pipable.pipe(fun,...args)` : Return a pipable object.
    
    `fun` is a function, `args` are the rest arguments you want pipe to `fun`.
    
    -   If `args` do not included placeholder `_`, `fun` will be called as
        `fun(...[v,...args])`.
    
    -   If `args` included one and only one placeholder `_`, `pipable.valueOf()` will 
        instead of the placehoder, and `fun` will be called as 
        `fun(...args)`.

-   `pipable.map(fun,...args)` : `pipable.map` is the alias of `pipable.pipe`.
-   `pipable.promise_rescue(fun,...args)`: return a new pipable object.
    -   when the `pipable.vlaueOf()` is a promise and the promise is reject, 
        the reject reason will pipe to `fun`.
    -   when `pipeable.valueOf()` is not a promise, `fun` will been skiped and return 
        copy of `pipable`.

## Use placeholder set which argument of `fun` take the piped value

    test('pipe with placeholder', () => {
      let fn = jest.fn((a, b, c) => a + b + c);
      let z = pipe('a').pipe(fn, 'b', 'c');
      expect(fn).not.toHaveBeenCalled();
      expect(z == 'abc').toBe(true);
      expect(fn).toBeCalledWith('a', 'b', 'c');
      z = pipe("2").pipe(fn, "1", _, "3");
      expect(z == '123').toBe(true);
      expect(fn).toBeCalledWith('1', '2', '3');
      z = pipe('e').pipe(fn, 'a', 'b', 'c', 'd', _);
      expect(z == 'abc');
      expect(fn).toHaveBeenLastCalledWith('a', 'b', 'c', 'd', 'e');
    })

## `pipable.pipe(fun,...args)` keep `pipable` object immutable.

`pipable.pipe(fn,...args)` will return a new pipable object,don't change the old one.

    test('pipable is independ', () => {
      let a = 1;
      let fn1 = jest.fn(a => a + 1);
      let fn2 = jest.fn((b, c) => b + c);
      let pipable0 = pipe(a);
      let pipable1 = pipable0.pipe(fn1);
      expect(pipable1 == a + 1).toBe(true);
      expect(pipable0.valueOf()).toBe(a);
      let pipable2 = pipable1.pipe(fn2, 'c');
      expect(pipable2 == '2c').toBe(true);
      expect(pipable1.valueOf()).toBe(a + 1);
    })

## `pipable.pipe(fn,...args)` is lazy

Call `pipeable.pipe(fn,...args)` do not call `fn`,
but `pipable.valueOf()`  will call the `fn` if there have one.
As fellow show:

    test(`pipable is layze`, () => {
      const fn = jest.fn(a => a + 1);
      let pipable0 = pipe(1);
      let ret = pipable0.pipe(fn).pipe(fn).pipe(fn);
      expect(fn).not.toHaveBeenCalled();
      expect(ret.valueOf()).toBe(1 + 1 + 1 + 1);
      expect(fn.mock.calls).toMatchObject([[1], [2], [3]]);
    })

## `pipable<Promise>.pipe(fn,...args)`

If the value of a pipable is a `Promise`, 
`pipable.pipe(fn)` pipe the resolve value of the promise to `fn`,
and return a new promise pipable.

### Examaples

    test('pipe promise resolve ', (done) => {
      let a = from(Promise.resolve(1));
      expect(a.valueOf()).toBeInstanceOf(Promise);
      let fn = jest.fn(a => a + 1);
      let ret = a.pipe(fn).
        promise_rescue(fn).//skip
        pipe(fn).valueOf();
      expect(ret).toBeInstanceOf(Promise);
      ret.then(() => {
        expect(fn.mock.calls).toMatchObject([[1], [2]]);
        done();
      });
    })

## `pipable<Promise>.promise_rescue`:

Return a new pipable<Promise>.

If value of `pipable<Promise>` is reject, this method can rescue from the error.

    test('pipe promise reject', (done) => {
      let a = from(Promise.reject('hello'));
      let fn1 = jest.fn(a => 'fn1');
      let fn2 = jest.fn(a => 'fn2');
      let fn3 = jest.fn(a => "fn3");
      let promise = a.pipe(fn1).//skip
        promise_rescue(fn2).//call
        pipe(fn3).valueOf();
      expect(promise).toBeInstanceOf(Promise);
    
      promise.then(
        (a) => {
          expect(fn1).not.toHaveBeenCalled();
          expect(fn2).toHaveBeenCalledWith('hello');
          expect(fn3).toHaveBeenCalledWith('fn2');
          expect(a).toBe('fn3');
          done();
        },
        (error) => {
          console.error(error);
          expect('not run to here').toBe('but it is here');
        }
      )
    })

# not: `not(fn)=>Function`

Negative `fun`.

If `fun` is a predicater, return a new negative predicater.
If `fun` is a compare function, return the negative compare function.

## Parameters

-   `fun` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** :~(v,&#x2026;args)=>Boolean|Number~

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** other\_fun: `(v,...args)=>Boolean|Number`

## Examples

    const not = require('./not');
    test('not(p)', () => {
      let p = n => n % 2 == 0;
      expect(not(p)(2)).toBe(!p(2));
      expect(not(p)(1)).toBe(!p(1));
      expect(not((a, b) => a - b)(1, 2)).toBe(2 - 1);
    })

# selectWith: `predicate=>array=>Array`

select some array with `predicate`.

Support there is an `array` include value `v`, and `predicate(v)` is true,
then `select(array)` will include `v`.

## Parameters

-   `predicate` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** (v,index)=>Boolean;

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** select: (array)=>array

## Examples

    let array = [1, 2, 3, 4];
    let arrayb = [5, 6, 7, 8];
    const isOlder = d => d % 2 == 0;
    test('selectWith(fun,array)', () => {
      const selectOld = selectWith(isOlder);
      expect(selectOld(array)).toMatchObject([2, 4]);
      expect(selectOld(arrayb)).toMatchObject([6, 8]);

# rejectWith: `predicate=>array=>Array`

Reject some array with `predicate`.

Support there is an `array` include value `v`,and `predicate(v)` is true,
then `reject(array)` will ****not**** include `v`.

## Parameters

-   `predicate` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** : (v,index)=>Boolean;

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** reject:(array)=>array

    test('rejectWith(isOlder)', () => {
      const rejectOlder = rejectWith(isOlder);
      expect(rejectOlder(array)).toMatchObject([1, 3]);
      expect(rejectOlder(arrayb)).toMatchObject([5, 7]);
    })

# orderWith: ~(compare[,{asc}])=>array=>Array

Order a array with a `compare` function.
When `asc` is `true`, sort value in ascending order else in descending.

For `compare(a,b)`, in asc order,
if you want `a` in front of `b`, return a negative number; 
if your want `b` in front of `a` return a positive number;
else you do not care which first return zero.

## Parameters

-   `compare` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** :~(a,b)=>Boolean~ (optional, default `(a,b)=>a-b`)
-   `$1` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**  (optional, default `{}`)
    -   `$1.asc`   (optional, default `true`)

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** order:(array)=>array

## Examples

    test('orderWith(fun)', () => {
      let sortByZ = orderWith((a, b) => a.z - b.z);
      let array = [{ a: 1, z: 2 }, { a: 2, z: 1 }, { a: 3, z: -1 }];
      let first = array[0];
      let ret = sortByZ(array);
      expect(ret).toMatchObject([{ a: 3, z: -1 }, { a: 2, z: 1 }, { a: 1, z: 2 }]);
      expect(ret[2]).toBe(first)
      expect(array[0]).toBe(first);
    });
    
    test('orderWith(fun,{asc=false})', () => {
      let sortByZ = orderWith((a, b) => a.z - b.z, { asc: false });
      let array = [{ a: 1, z: 2 }, { a: 2, z: 1 }, { a: 3, z: -1 }];
      let ret = sortByZ(array);
      expect(ret).toMatchObject(array);
      expect(ret).not.toBe(array);
      expect(ret[0]).toBe(array[0]);
    });

# reverse: `(array)=>Array`

Get a reversed **new** the array from `array`.

## Parameters

-   `array` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)**

Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** 

### Examples

    test('reverse(array)', () => {
      let array = [1, 2, 3, 4];
      expect(reverse(array)).toMatchObject([4, 3, 2, 1]);
      expect(array).toMatchObject([1, 2, 3, 4]);
    })

# zip: `(aIterable,arrayLikly)=>Array<Array(2)>`

Zip arrays `a1` and `a2` to an array of array.

## Parameters

-   `aIterable` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)**
-   `arrayLikly` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)**

Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** Array&lt;Array(2)>

## Examples

    test('zip(a1,a2)', () => {
      const a1 = [1, 2, 3, 4];
      const a2 = ['one', 'two', 'three'];
      const ret1 = zip(a1, a2);
      expect(ret1).toMatchObject([[1, 'one'], [2, 'two'], [3, 'three'], [4, undefined]]);
      expect(zip(a2, a1)).toMatchObject([['one', 1], ['two', 2], ['three', 3]]);
    })

# every: `(fun,iterable)=>boolean`

Check is `every` element in `iteratble` satisfy contiontion `fun`.

If `iterable` is empty, return `true`. See more at 
[here](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every*Description>);

## Parameters

-   `fun` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** :~(element[,index,array])~
-   `iterable` ****Iterable****

Returns ****any**** boolean

## Examples

    test('every(funp,arrayLikly)', () => {
      expect(every(positive, [1, 2, 3, 4])).toBe(true);
      expect(every(positive, [1, 2, -1, 3, 4])).toBe(false)
      expect(every(positive, [])).toBe(true)
    })

# all: `(fun,iterable)=>boolean`

Check is `all` element in `iteratble` satisfy contiontion `fun`.

This is similarity as [every](#every) but if `iterable` is empty, return `false`.

## Parameters

-   `fun` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** : `(element[,index,array])=>boolean`
-   `iteratable` ****Iterable****

## Examples

    const positive = a => a > 0;
    test('all(funp,arrayLike)', () => {
      expect(all(positive, [1, 2, 3, 4])).toBe(true);
      expect(all(positive, [1, 2, -1, 3, 4])).toBe(false)
      expect(all(positive, [])).toBe(false)
    })

# every: `(fun,iterable)=>boolean`

Similarity as , but if `iterable` is empty, return `true`.

# any: `(fun,iterable)=>boolean`

Check is `some` element in `iterable` satisfy contiontion `fun`.

## Parameters

-   `fun` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** : `(element[,index,array])=>boolean`
-   `iterable` ****Iterable****

## Examples

    test('any(funp,arrayLikly)', () => {
      expect(any(positive, [-1, -2, -3, 4])).toBe(true);
      expect(any(positive, [-1, -2, -3, -4])).toBe(false);
      expect(any(positive, [])).toBe(false);
      expect(any(positive, [0])).toBe(false);
      expect(any(positive, [+0])).toBe(false);
      expect(any(positive, [-0])).toBe(false);
    })

# some: `(fun,iterable)=>boaolean`

Alias of .