Skip to content

Commit

Permalink
feat: 🎸 add accum operator
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriz committed Dec 26, 2022
1 parent 275e35d commit 60072fd
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 24 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ All notable changes to this project will be documented in this file. See [standa

### ⚠ BREAKING CHANGES

* 🧨 old curry2 became multiCurry2 to avoid collision with ramda's curryN
* 🧨 old curry2 became curryGroups2 to avoid collision with ramda's curryN

### Features

* 🎸 add multiCurry functions ([7a1eb52](https://github.com/dmitriz/cpsfy/commit/7a1eb520e1dc696742fe3940d4328d91adfc3870))
* 🎸 add curryGroups functions ([7a1eb52](https://github.com/dmitriz/cpsfy/commit/7a1eb520e1dc696742fe3940d4328d91adfc3870))

## [3.9.0](https://github.com/dmitriz/cpsfy/compare/v3.8.0...v3.9.0) (2022-12-25)

Expand Down
24 changes: 19 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@ const { isNil, mergeArray, inheritPrototype } = require('./utils')

/* ----- General purpose utils ----- */

exports.multiCurry2 = f => (...a) => (...b) => f(...a, ...b)
exports.curryGroups2 = f => (...a) => (...b) => f(...a, ...b)

exports.multiCurryN = n => f => {
exports.curryGroupsN = n => f => {
while(--n > 0) {
f = exports.multiCurry2(f)
f = exports.curryGroups2(f)
}
return f
}

/**
* Transform `reducer: (state,next) => state` into accumulator function updating state inside closure.
*
* @param {Function} reducer: (state,next) -> state
* @returns {Function} accum(reducer): initState -> (x0,...,xn) -> reducer(prevState,x0,...,xn)
*
* @example accumulator = accum((state,x) => state+x)
* acc = accumulator(5) // initialize accumulator function with initial state = 5
* acc(2) //=> 5+2
* acc(2) //=> 5+2+2
* acc(4) //=> 5+2+2+4
*/
exports.accum = reducer => state => (...vals) => {state = reducer(state, ...vals); return state}


/**
* Pass tuple of values to sequence of functions similar to UNIX pipe
Expand Down Expand Up @@ -234,7 +248,7 @@ const filter = (...preds) => {
* @param {Function} cpsFn - CPS function.
* @returns {Function} `scan(...reducers, init)(cpsFn)`
* - CPS function whose output from the first callback
* is the accumulated value. For each output `(y1, y2, ...)`
* is the accumd value. For each output `(y1, y2, ...)`
* from the `n`th callback of `cpsFn, the `n`th reducer `redn`
* is used to compute the new acculated value
* `redn(acc, y1, y2, ...)`, where `acc` starts with `init`,
Expand Down Expand Up @@ -320,7 +334,7 @@ const ap = (...fns) => cpsFn => {
* Lift binary function to act on values wraped inside CPS functions
*/
exports.lift2 = f => (F1, F2) => pipeline(F2)(
ap(map(exports.multiCurryN(2)(f))(F1))
ap(map(exports.curryGroupsN(2)(f))(F1))
)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"cov": "npx tap test/*test.js --coverage-report=lcov",
"rebcont": "git add . && git rebase --continue",
"toc": "npx markdown-toc DOCUMENTATION.md > toc",
"doc": "npx documentation build 'index.js' -f html -o auto-docs",
"doc": "npx documentation build 'index.js' -f html -o auto-docs --github",
"test": "npm run ava",
"testw": "npm run avaw"
},
Expand Down
Empty file added state
Empty file.
16 changes: 16 additions & 0 deletions test/accum.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const test = require('./config')
const { accum } = require('..')

test('accum transforms simple reducer to accumulator', t=>{
const add = accum((state,v)=>state+v)(10)
t.is(add(1),10+1)
t.is(add(2),10+1+2)
t.is(add(-1),10+1+2-1)
})

test('accum works with reducer with variadic tuples of values', t=>{
const concat = accum((arr, ...rest)=>arr.concat(rest))([0])
t.deepEqual(concat(1),[0,1])
t.deepEqual(concat(),[0,1])
t.deepEqual(concat(1,2,3),[0,1,1,2,3])
})
10 changes: 5 additions & 5 deletions test/multiCurry2.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const test = require('./config')
const { multiCurry2 } = require('..')
const { curryGroups2 } = require('..')

test('multiCurry2 arg function', t => {
t.is( multiCurry2((a,b)=>a+b)(1)(2), 3)
test('curryGroups2 arg function', t => {
t.is( curryGroups2((a,b)=>a+b)(1)(2), 3)
})

test('multiCurry2 3 arg function', t => {
t.is( multiCurry2((a,b,c)=>a+b+c)(1,2)(3), 6)
test('curryGroups2 3 arg function', t => {
t.is( curryGroups2((a,b,c)=>a+b+c)(1,2)(3), 6)
})
22 changes: 11 additions & 11 deletions test/multiCurryN.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
const test = require('./config')
const { multiCurryN } = require('..')
const { curryGroupsN } = require('..')

const add = (x,y)=>x+y
const collect = (...args) => args

test('multiCurryN(1) does not change function', t=>{
t.is(multiCurryN(1)(add)(11,22), 11+22)
t.deepEqual(multiCurryN(1)(collect)(11,22), [11,22])
test('curryGroupsN(1) does not change function', t=>{
t.is(curryGroupsN(1)(add)(11,22), 11+22)
t.deepEqual(curryGroupsN(1)(collect)(11,22), [11,22])
})

test('multiCurryN applied to 2 groups of args', t=>{
t.deepEqual(multiCurryN(2)(collect)(11)(22), [11,22])
t.deepEqual(multiCurryN(2)(collect)(11,2)(22,3,1), [11,2,22,3,1])
test('curryGroupsN applied to 2 groups of args', t=>{
t.deepEqual(curryGroupsN(2)(collect)(11)(22), [11,22])
t.deepEqual(curryGroupsN(2)(collect)(11,2)(22,3,1), [11,2,22,3,1])
})

test('multiCurryN applied to 3 groups of args', t=>{
t.deepEqual(multiCurryN(3)(collect)(11,2)(22)(3,1), [11,2,22,3,1])
test('curryGroupsN applied to 3 groups of args', t=>{
t.deepEqual(curryGroupsN(3)(collect)(11,2)(22)(3,1), [11,2,22,3,1])
})

test('multiCurryN applied to 4 groups of args', t=>{
t.deepEqual(multiCurryN(4)(collect)(11,2)(22)(3)(1), [11,2,22,3,1])
test('curryGroupsN applied to 4 groups of args', t=>{
t.deepEqual(curryGroupsN(4)(collect)(11,2)(22)(3)(1), [11,2,22,3,1])
})

0 comments on commit 60072fd

Please sign in to comment.