Skip to content

Commit

Permalink
calling it rmap, rmapValues for plain objects and a test with Set
Browse files Browse the repository at this point in the history
  • Loading branch information
sadasant committed Feb 26, 2017
1 parent 12d78fb commit f13af70
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
8 changes: 5 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ export const flowMap = (...fns) => _.map(_.flow(...fns))

// Algebras
// --------
// Folding recursive algebraic data types
export const fold = _.curry((fn, obj, map = _.mapValues, is = _.isPlainObject) =>
map(e => is(e) ? fold(fn, fn(e), map, is) : e, obj))
// Map for any recursive algebraic data structure
// defaults in multidimensional arrays
export const rmap = _.curry((fn, obj, map = _.map, is = _.isArray) =>
map(e => is(e) ? rmap(fn, fn(e), map, is) : e, obj))
export const rmapValues = _.curry((fn, obj) => rmap(fn, obj, _.mapValues, _.isPlainObject))

// Misc
// ----
Expand Down
47 changes: 38 additions & 9 deletions test/algebras.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@ chai.expect()
const expect = chai.expect

describe('Algebras', () => {
it('fold defaults for plain objects', () => {
it('rmap', () => {
const arr = [ 0, [ 1, [ 2, [ ] ] ] ]

const arrBackup = _.cloneDeep(arr)

const arrMutated = f.rmap(e => e.concat(101), arr)

// Checking immutability
expect(arr).to.eql(arrBackup)

expect(arrMutated).to.eql([ 0, [ 1, [ 2, [ 101 ], 101 ], 101 ] ])
})

it('rmapValues', () => {
const obj = {
a: {
match: {
Expand All @@ -28,7 +41,7 @@ describe('Algebras', () => {

const path = 'match.matched'
const setMatched = e => e.match && _.set(path, true, e)
const objMutated = f.fold(e => setMatched(e) || e)(obj)
const objMutated = f.rmapValues(e => setMatched(e) || e)(obj)

// Checking immutability
expect(obj).to.eql(objBackup)
Expand All @@ -55,16 +68,32 @@ describe('Algebras', () => {
})
})

it('folding arrays', () => {
const arr = [ 0, [ 1, [ 2, [ ] ] ] ]
it('rmap Sets', () => {
const setRoot = new Set()
const set1 = new Set()
const set2 = new Set()
setRoot.add(0)
setRoot.add(set1)
set1.add(1)
set1.add(set2)
set2.add(2)

const arrBackup = _.cloneDeep(arr)
const map = (f, s) => {
const values = []
for (let v of s.values()) {
values.push(v)
}
for (let v of values) {
s.delete(v)
s.add(f(v))
}
return s
}

const arrMutated = f.fold(e => e.concat(101), arr, _.map, _.isArray)
const is = s => Object.prototype.toString.call(s) === '[object Set]'

// Checking immutability
expect(arr).to.eql(arrBackup)
const setMutated = f.rmap(s => s.add(101), setRoot, map, is)

expect(arrMutated).to.eql([ 0, [ 1, [ 2, [ 101 ], 101 ], 101 ] ])
expect(JSON.stringify(setMutated)).to.equal('[0,[1,[2,101],101]]')
})
})

0 comments on commit f13af70

Please sign in to comment.