diff --git a/src/index.d.ts b/src/index.d.ts index 42130d6cb6..509e309109 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -301,6 +301,12 @@ declare namespace RamdaAdjunct { */ resetToDefault(defaultOptions: Object, options: Object): Object; // alias of mergeRight resetToDefault(defaultOptions: Object): (options: Object) => Object; // alias of mergeRight + + /** + * Weave a configuration into function returning the runnable monad like `Reader` or `Free`. + */ + weave(fn: Function, config: any): Function; + weave(fn: Function): (config: any) => Function; } } diff --git a/src/index.js b/src/index.js index b14422109f..7e3b939807 100644 --- a/src/index.js +++ b/src/index.js @@ -42,6 +42,7 @@ import noop from './noop'; import liftFN from './liftFN'; import liftF from './liftF'; import cata from './cata'; +import weave from './weave'; // List import pickIndexes from './pickIndexes'; import list from './list'; @@ -102,6 +103,7 @@ export { default as noop } from './noop'; export { default as liftFN } from './liftFN'; export { default as liftF } from './liftF'; export { default as cata } from './cata'; +export { default as weave } from './weave'; // List export { default as pickIndexes } from './pickIndexes'; export { default as list } from './list'; @@ -167,6 +169,7 @@ const RA = { liftFN, liftF, cata, + weave, // List pickIndexes, list, diff --git a/src/weave.js b/src/weave.js new file mode 100644 index 0000000000..646c0ca8a3 --- /dev/null +++ b/src/weave.js @@ -0,0 +1,31 @@ +import { curryN } from 'ramda'; + +/** + * Weave a configuration into function returning the runnable monad like `Reader` or `Free`. + * + * @func weave + * @memberOf RA + * @since {@link https://char0n.github.io/ramda-adjunct/1.7.0|v1.7.0} + * @category Function + * @sig (*... -> *) -> * -> (*... -> *) + * @param {Function} fn The function to weave + * @param {*} config The configuration to weave into fn + * @return {Function} + * @example + * + * const { Reader: reader } = require('monet'); + * + * const log = value => reader( + * config => config.log(value) + * ); + * + * // no weaving + * log('test').run(console); //=> prints 'test' + * + * // weaving + * const wlog = RA.weave(log, console); + * wlog('test'); //=> prints 'test' + */ +const weave = curryN(2, (fn, config) => (...args) => fn(...args).run(config)); + +export default weave; diff --git a/test/weave.js b/test/weave.js new file mode 100644 index 0000000000..1558cc91f7 --- /dev/null +++ b/test/weave.js @@ -0,0 +1,34 @@ +import { curryN } from 'ramda'; +import { Reader as reader } from 'monet'; + +import RA from '../src/index'; +import eq from './shared/eq'; + + +describe('weave', function() { + const unaryReader = a => reader(config => config + a); + const binaryReader = (a, b) => reader(config => config + a + b); + + it('tests weaving', function() { + const wunaryReader = RA.weave(unaryReader, 1); + const wbinaryReader = RA.weave(binaryReader, 1); + + eq(wunaryReader(1), 2); + eq(wbinaryReader(2, 3), 6); + }); + + it('tests currying', function() { + const wbinaryReader1 = RA.weave(binaryReader, 1); + const wbinaryReader2 = RA.weave(binaryReader)(1); + + eq(wbinaryReader1(2, 3), 6); + eq(wbinaryReader2(2, 3), 6); + }); + + it('tests curried weaving', function() { + const wbinaryReader = curryN(2, RA.weave(binaryReader, 1)); + + eq(wbinaryReader(2, 3), 6); + eq(wbinaryReader(2)(3), 6); + }); +});