Closed DrBoolean closed 8 years ago
The idea of traversed
is that it allows a lens-like traversal of any Traversable
type, targeting each value contained within. It achieves this by using the applicative instances of Const
and Identity
as a wrapper for the type contained within the Traversable
for use with foldMapOf
and over
.
So we're effectively making the most of the convenience that traverse
has a signature that fits what we expect to provide as the optic for functions like over
and foldMapOf
.
type Lens s t a b = Functor f => (a -> f b) -> s -> f t
type Traversal s t a b = Applicative f => (a -> f b) -> s -> f t
R.traverse :: Applicative f, Traversable t => (a -> f a) -> (a -> f b) -> t a -> f (t b)
-- a.k.a
R.traverse :: Applicative f, Traversable t => (a -> f a) -> Traversal (t a) (t b) a b
So it's expected output could be something like:
const everyX = compose(traversed, lensProp('x'));
over(everyX, R.inc, List.of({ x: 1 })) //=> List.of({ x: 2 })
Interesting... So what's the difference between the mapped
lens and traversed
?
I ask because
const everyX = compose(mapped, lensProp('x'));
over(everyX, R.inc, List.of({ x: 1 })) //=> List.of({ x: 2 })
is equivalent here, yes?
For over
, yep. But mapped
is just a Setter
, so it can't be used to extract values for foldMapOf
.
Ahh, thanks @scott-christopher - I had traversed all wrong
One last question then...is there a way to do what i'm looking to do above? I want to "traverse" the Task lens style.
Interestingly, you can just give the function you'd normally give to traverse to the lens because traverseOf == identity
.
Unfortunately, because we don't have the type system available to give us the of
function necessary for the Traversable we need to piggyback off of our previous "workaround" for traversed
by using the this
context of the lens to provide the function for creating our Applicative.
So something like this should work (... I think)
const traverseOf = (of, lens, f, target) => lens.call({ of }, f)(target);
const thing = List.of({ x: 1 });
const everyX = compose(traversed, lensProp('x'));
traverseOf(Task.of, everyX, y => Task.of(y + 1), thing); //=> Task.of(List.of({ x: 2 }))
I'll give it a shot. Thanks a million!
Just starting to make heavy use of this (finally). I kind of want to use your profunctor version instead though :)
Just realized... https://github.com/ramda/ramda-lens/commit/ce6ea28fb31dd8e29d5f0d81557cd2495aef6144#diff-c1129c8b045390789fa8ff62f2c6b4a9L85
Should match if i understand traversals correctly. However, it might be the case that I don't...