-
-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ref #56
- Loading branch information
Showing
4 changed files
with
83 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { curry, last, slice, reverse, reduce, pipe, ap, curryN, map, flip } from 'ramda'; | ||
|
||
/** | ||
* "lifts" a function to be the specified arity, so that it may "map over" objects that satisfy | ||
* the Apply spec of algebraic structures. This function is not compatible | ||
* with {@link https://github.com/fantasyland/fantasy-land#apply|FantasyLand Apply spec}. | ||
* | ||
* Lifting is specific for {@link https://github.com/scalaz/scalaz|scalaz} and {@link http://www.functionaljava.org/|functional java} implementations. | ||
* One of the mainstream libraries that uses this Apply spec is {@link https://cwmyers.github.io/monet.js/|monet.js}. | ||
* This function acts as interop for ramda and monet.js. | ||
* | ||
* More info {@link https://github.com/fantasyland/fantasy-land/issues/50|here}. | ||
* | ||
* @func liftFN | ||
* @memberOf RA | ||
* @since {@link https://char0n.github.io/ramda-adjunct/1.2.0|v1.2.0} | ||
* @category Function | ||
* @sig Apply a => Number -> (a... -> a) -> (a... -> a) | ||
* @param {Function} fn The function to lift into higher context | ||
* @return {Function} The lifted function | ||
* @see {@link http://ramdajs.com/docs/#lift|lift}, {@link http://ramdajs.com/docs/#ap|ap} | ||
* @example | ||
* | ||
* const { Maybe } = require('monet'); | ||
* | ||
* const add3 = (a, b, c) => a + b + c; | ||
* const madd3 = RA.liftFN(3, add3); | ||
* | ||
* madd3(Maybe.Some(10), Maybe.Some(15), Maybe.Some(17)); //=> Maybe.Some(42) | ||
* madd3(Maybe.Some(10), Maybe.Nothing(), Maybe.Some(17)); //=> Maybe.Nothing() | ||
*/ | ||
const liftFN = curry((arity, fn) => { | ||
const lifted = curryN(arity, fn); | ||
return curryN(arity, (...args) => { | ||
const accumulator = map(lifted, last(args)); | ||
const apps = pipe(slice(0, arity - 1), reverse)(args); | ||
return reduce(flip(ap), accumulator, apps); | ||
}); | ||
}); | ||
|
||
export default liftFN; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Maybe } from 'monet'; | ||
import { add, reduce, curry } from 'ramda'; | ||
|
||
import RA from '../src/index'; | ||
import eq from './shared/eq'; | ||
|
||
|
||
const addN = (...args) => reduce(add, 0, args); | ||
const add3 = curry((a, b, c) => a + b + c); | ||
|
||
describe('liftFN', function() { | ||
const addN3 = RA.liftFN(3, addN); | ||
const addN4 = RA.liftFN(4, addN); | ||
const addN5 = RA.liftFN(5, addN); | ||
|
||
it('returns a function', function() { | ||
eq(typeof RA.liftFN(3, add3), 'function'); | ||
}); | ||
|
||
it('limits a variadic function to the specified arity', function() { | ||
eq(addN3(Maybe.Some(1), Maybe.Some(1), Maybe.Some(1), Maybe.Some(1)), Maybe.Some(3)); | ||
}); | ||
|
||
it('can lift functions of any arity', function() { | ||
eq(addN3(Maybe.Some(1), Maybe.Some(1), Maybe.Some(1)), Maybe.Some(3)); | ||
eq(addN4(Maybe.Some(1), Maybe.Some(1), Maybe.Some(1), Maybe.Some(1)), Maybe.Some(4)); | ||
eq( | ||
addN5(Maybe.Some(1), Maybe.Some(1), Maybe.Some(1), Maybe.Some(1), Maybe.Some(1)), | ||
Maybe.Some(5) | ||
); | ||
}); | ||
|
||
it('is curried', function() { | ||
const f4 = RA.liftFN(4); | ||
eq(typeof f4, 'function'); | ||
eq(f4(addN)(Maybe.Some(1), Maybe.Some(1), Maybe.Some(1), Maybe.Some(1)), Maybe.Some(4)); | ||
}); | ||
}); |