DEV Community

artydev
artydev

Posted on • Updated on

Some functional utilities

Here are some utilities I use, when I don't want to rely on any external libraries :


const curry = function (fn) {
  const curried = (...args) => {
    if (args.length >= fn.length) {
      return fn.apply({}, args)
    }
    else {
      return (...vargs) => curried.apply({}, args.concat(vargs))
    }
  }
  return curried
}

const compose = 
    (...fns) => arg => fns.reduceRight((acc, f) => f(acc), arg);

const pipe = 
    (...fns) => arg => fns.reduce((acc, f) => f(acc), arg);

const asyncpipe = 
    (...fns) => arg => fns.reduce((p, fn) => p.then(fn), Promise.resolve(arg));

const pickprop = (prop) => (obj) => obj[prop] ?? null; 

const map = (f) => (arr) => arr.map(f);

const filter = (f) => (arr) => arr.filter(f);

Enter fullscreen mode Exit fullscreen mode

The function passed to the reduce method is called a reducer.

A reducer is a function which has two arguments, the first of type A, the second of type B and the returned type is of type A.

As long as any function has this signature, it can be passed to a reduce method.

Top comments (2)

Collapse
 
efpage profile image
Eckehard

Hy,

why did you not use the "nullish coalescing operator" (what a horrible name...):

const pickprop = (prop) => (obj) =>  obj[prop] ?? null
Enter fullscreen mode Exit fullscreen mode

By the way , is there any good reason to use this kind nested arrow functions here? Ok, you can generate functions like this:

test_b = pickprop("b")
        d = test_b(ob)
Enter fullscreen mode Exit fullscreen mode

but usually I would think we use this kind of functions to pick unsure parameters:

const pickprop = (obj, prop) =>  obj[prop] ?? null

let ob = { a: true, b: false }

let myPar = pickprop(ob,"c")
let myPar = ob.c ?? null  // same result
Enter fullscreen mode Exit fullscreen mode
Collapse
 
artydev profile image
artydev • Edited

Hy Eckehard :-)

Thank you for "nullish coalescing operator",sometimes I am really blind :-).

For the particular function, it is because I use it in pipe function, like

const owner = pickprop("owner");
const petname =  pickprop("petname")
const contribution = pickprop("contribution");
const payed = pickprop("payed");

const ownerpayed =  pipe(owner, contribution, payed)
const ownername = pipe(owner, pickprop("ownername"))
Enter fullscreen mode Exit fullscreen mode

And the chained functions accept only 1 argument.
The resulting "pipe" function will receive the final object as argument.

Thank you again for correcting me, and your suggestions :-)