Skip to content

Curry a function with dictionary (object) aguments

License

Notifications You must be signed in to change notification settings

anisotropy/dcurry

Repository files navigation

dcurry

한국어 버전

dcurry curries a given function. However, unlike Ramda.curry, the arguments for this function must be a single dictionary (object). For example, if f is a function that takes an argument of type { a: number, b: number, c: number } and g is dcurry(['a', 'b', 'c'], f), the following expressions are equivalent:

  • g({ a: 1 })({ b: 2 })({ c: 3 })
  • g({ a: 1, b: 2 })({ c: 3 })
  • g({ a: 1 })({ b: 2, c: 3 })
  • g({ a: 1, b: 2, c: 3 })

The advantage of dcurry over Ramda.curry is that you don't need to consider the order of arguments. In the case of Ramda.curry, if you want to create a function that takes the first argument, you need to use a somewhat awkward placeholder R.__, like this:

g(R.__, 2, 3)

In the case of dcurry, you just need to input all arguments except the first one:

g({ b: 2, c: 3 })

Therefore, the following cases all mean the same thing:

  • g({ c: 3 })({ b: 2 })({ a: 1 })
  • g({ b: 2 })({ c: 3 })({ a: 1 })
  • g({ c: 2 })({ a: 1, c: 3 })
  • g({ a: 1, b: 3 })({ b: 2 })

Installation

pnpm add dcurry

or

npm i dcurry

Usage

dcurry

For example, if you have the following function:

const fn = (params: { a: number; b: number; c: number }) => `${a}-${b}-${c}`

To curry this function, you need to input an array of all keys of the dictionary given as an argument to dcurry as the first argument:

import { dcurry } from 'dcurry'

const curriedFn = dcurry(['a', 'b', 'c'], fn)

The curried function curriedFn can be used as follows:

const curriedFn2 = curriedFn({ b: 2, c: 3 })
curredFn2({ a: 1 }) // -> 1-2-3

If there are optional keys in the dictionary given as an argument, when entering the value for that key, you must use undefined:

const fn = (params: { a?: number; b: number; c: number }) => `${a ?? 'a'}-${b}-${c}`

const curriedFn = dcurry(['a', 'b', 'c'], fn)

const curriedFn2 = curriedFn({ b: 2, c: 3 })
curredFn2({ a: undefined }) // -> a-2-3

toDictParams

toDictParams transforms a function with array parameters into a function with dictionary parameters.

const fn = (a: number, b?: string) => `${a}-${b}`

toDictParams(['a', 'b'], fn) // -> ({ a: number, b?: string }) => string

Note that using default parameters is not allowed.

const fn = (a: number, b = '3') => `${a}-${b}`

toDictParams(['a', 'b'], fn) // This will result in an error.

toArrParams

toArrParams transforms a function with dictionary parameters into a function with array parameters.

const fn = (params: { a: number; b?: string }) => `${params.a}-${params.b}`

toArrParams(['a', 'b'], fn) // -> (a: number, b?: string) => string