calmm-js / partial.lenses

Partial lenses is a comprehensive, high-performance optics library for JavaScript
MIT License
915 stars 36 forks source link

I'd like to L.traverse an object #193

Closed mweichert closed 6 years ago

mweichert commented 6 years ago

Any suggestions of how to go about this?

E.g.

const structure = {
    foo: 'bar',
    foobar: {
        foo: 2,
        bar: 4
    }
}

const optic = ['foobar', L.values]

L.traverse(Future, later, optic, structure).fork(console.log, console.log)
polytypic commented 6 years ago

I assume Future comes from the fluture package. Partial Lenses uses static land, so what one needs to do is to construct a static land compatible applicative. For example:

const Future = require("fluture")
const L = require("partial.lenses")

const structure = {
  foo: 'bar',
  foobar: {
    foo: 2,
    bar: 4
  }
}

const optic = ['foobar', L.values]

const fromFantasy = of => ({
  of,
  map: (f, x) => x['fantasy-land/map'](f),
  ap: (f, x) => x['fantasy-land/ap'](f),
  chain: (f, x) => x['fantasy-land/chain'](f)
})

L.traverse(
  fromFantasy(Future.of),
  x => Future.of(x + 1),
  optic,
  structure
).fork(
  err => console.log('Error', err),
  res => console.log('Result', res)
)

Here is the above code in RunKit.

BTW, whether you are just trying out or using the library, I recommend joining the Gitter channel.

Edit: Made the example actually use the Fantasy Land methods.

polytypic commented 6 years ago

Working on #194

polytypic commented 6 years ago

Oh... Of course, given that Future of fluture is already static land compatible, you don't need to convert to static land. So, the following also just works:

const Future = require("fluture")
const L = require("partial.lenses")

const structure = {
  foo: 'bar',
  foobar: {
    foo: 2,
    bar: 4
  }
}

const optic = ['foobar', L.values]

L.traverse(
  Future,
  x => Future.of(x + 1),
  optic,
  structure
).fork(
  err => console.log('Error', err),
  res => console.log('Result', res)
)

Here is the above code in RunKit.

Addition: And if you want the computation to finish "later", e.g. 5 seconds later, you could edit the above as:

-  x => Future.of(x + 1),
+  x => Future.after(5000, x + 1),
mweichert commented 6 years ago

Thanks @polytypic for the quick response and great assistance. I was using data.task actually but your examples gave me exactly what I needed to better understand traversals, traverse, and static land.