Ramda Adjunct 4.0.0

fnull.js

import { isNil, curryN, curry, apply } from 'ramda';

import defaultWhen from './defaultWhen';
import mapIndexed from './mapIndexed';

/**
 * Returns a function which is called with the given arguments. If any of the given arguments are null or undefined,
 * the corresponding default value for that argument is used instead.
 *
 * @func fnull
 * @memberOf RA
 * @category Function
 * @sig (a ... -> b) -> [c] -> a ... | c -> b
 * @param {Function} function to be executed
 * @param {Array} defaults default arguments
 * @return {Function} will apply provided arguments or default ones
 * @example
 *
 * const addDefaults = RA.fnull((a, b) => a + b, [4, 5])
 *
 * addDefaults(1, 2); // => 3
 * addDefaults(null, 2); // => 6
 * addDefaults(2, null); // => 7
 * addDefaults(undefined, undefined); // => 9
 */

const fnull = curry((fn, defaults) =>
  curryN(fn.length, (...args) => {
    const argsWithDefaults = mapIndexed(
      (val, idx) => defaultWhen(isNil, defaults[idx], val),
      args
    );

    return apply(fn, argsWithDefaults);
  })
);

export default fnull;