cliquer

Make a family of related functions from a naming function and an array of arguments


Keywords
curry, functional, boilerplate, reduction, library, clique, es2015, namer, primitive-values, ramda, sanctuary, shorthand
License
MIT
Install
npm install cliquer@0.1.6

Documentation

cliquer

Creates a group of related functions from a naming function, a value deriver function, and an array of primitive values.

Installation

yarn add cliquer

# or

npm i cliquer

API

clique()

clique :: (a -> String) -> (a -> Any) -> Array a -> Object

Takes a namer function, a function to derive a value, and an array of strings that becomes input for both functions, returns an object where each key value pair is generated by [namer, valueDeriver] respectively.

import { clique } from 'cliquer';

const concat = x => y => y.concat(x)
const always = x => () => x
const consts = clique(concat('Bar'), always)

const C = consts(['a', 'b'])
C.bBar() //=> 'b'

simpleClique()

simpleClique :: (a -> Any) -> Array a -> Object

This is simply clique partially applied with an identity function, so that each key is either a literal or toString representation of the input value.

import { simpleClique } from 'cliquer';

const always = x => () => x
const consts = simpleClique(always)

const C = consts(['a', 'b'])
C.b() //=> 'b'

How and why did this come to be?

Cliquer was originally inspired by a utility in drboolean's lenses library called makeLenses which takes an array of strings and returns an object of named lenses:

import { lensProp } from 'ramda'
import { makeLenses, view } from 'lenses'

const obj = {
  foe: { name: 'marley' },
  friend: { name: 'me' },
}

// makeLenses allows a DRY-er approach like
const L = makeLenses(['friend', 'name'])

// instead of
const friend = lensProp('friend')
const name = lensProp('name')

const friendName = compose(L.friend, L.name)
view(friendName, obj) // => 'me'

This got me thinking, how many things in javascript would benefit from a similar shortcut? So a simple curried factory function was born that took two functions, one to generate the key name, and one to define the function. Turns out this is a super useful pattern for creating utility groups.

import R from 'ramda'

const keys = ['beer', 'me']

// Pass an identity function so each key is named literally
const simpleClique = clique(x => x)

// Simple equality checks
const eqs = simpleClique(R.equals)
const E = eqs(keys)

E.beer('beer') //=> true
E.me('beer') //=> false


// Constant generators
const consts = simpleClique(R.always)
const C = consts(keys)

C.beer() //=> 'beer'


// Regex group
const firstChars = simpleClique(x => new RegExp(`^${x}`))
const F = firstChars(['a', 'b'])

R.test(F.a, 'abc') //=> true
R.test(F.b, 'abc') //=> false


/* Even more complex things! */

// Pass a function that names each key by appending `bird`
const birdClique =
  clique(x => x.concat('bird'))

const url =
  'https://isthisbirdathing.com/api/birds'

const birdFetchers =
  birdClique(x => fetch(`${url}/${x}bird`).then(x => x.json()) )

const B =
  birdFetchers(['blue', 'shoe', 'fackle'])

B.facklebird()
  .then(console.log) //=> { isAThing: 'um.. no' }

B.bluebird()
  .then(console.log) //=> { isAThing: 'yep 🐦' }

Get the picture? If not submit a PR to help me explain this better or to add more imaginative/hilarious examples 💖

What are you waiting for? Start some cliques 🍻