@scott-christopher : thanks for trying, that comment is completely over my head, can you recommend a good resource for learning that type annotation?

@SeeThruHead the type annotations are more or less taken from Haskell’s type defintions.

For the definition:

`Lens a b :: Functor f => (b -> f b) -> (a -> f a)`

You can think of `Lens a b`

as an alias for something that represents a lens with a focus on some type `b`

that can be accessed within some type `a`

. So `headLens`

that focussed on the first element of an array of strings would be a `Lens Array String`

if you swap out the `a`

and `b`

type variables.

The

`Functor f =>`

indicates a constraint such that any `f`

in the type signature that follows must be a `Functor`

(something that can be `map`

ped over)
`(b -> f b)`

can be read as a function that takes some type `b`

and returns a `Functor`

of `b`

s.
`(b -> f b) -> (a -> f a)`

can be read as a function which takes a `(b -> f b)`

function and returns an `(a -> f a)`

function.
It should be emphasized that the plumbing of lenses shouldn’t need to be understood to make use of them. If you stick with generating lenses via

`R.lens`

and use them via `R.over`

, `R.view`

and `R.set`

then you shouldn’t need to think about what a lens looks like on the inside.
If however you’re interested in understanding how they work, I’ll gladly have a go at explaining.

We can start by looking at how

`R.lens`

creates a lens from a `getter`

and `setter`

function to fit the type alias above (using ES6 arrows for brevity):```
// toFunctor :: focusType -> someFunctorOf focusType
// getter :: outerType -> focusType
// setter :: focusType -> outerType -> outerType
const lens(getter, setter) = toFunctor => outerThing =>
map(focusValue => setter(focusValue, outerThing), toFunctor(getter(outerThing)));
```

So if we were to create a

`headLens`

via `lens(R.head, R.update(0))`

, we’d end up with something equivalent to the following:```
const headLens = toFunctor => list =>
map(headVal => update(0, headVal, list), toFunctor(R.head(list)));
```

The trick to getting both setter and getter behaviour out of this one function lies in the

`toFunctor`

function passed as the first argument, which is used for lifting the output of the `getter`

function into a given functor.
We can then use the

`Const`

functor for getting a value (which happens in `R.view`

), or the `Identity`

functor for setting a value (which happens in `R.over`

and `R.set`

)
Mapping over a

`Const`

will always produce a constant value, essentially ignoring the mapping function. e.g.`R.map(R.add(1), Const(10)).value //=> 10`

And mapping over an

`Identity`

is effectively just applying the mapping function to the value in the `Identity`

. e.g.`R.map(R.add(1), Identity(10)).value //=> 11`

So the getter (`R.view`

) for `headLens`

would effectively be equivalent to:

`list => map(headVal => update(0, headVal, list), Const(R.head(list))).value`

and given that mapping over a `Const`

is effectively moot, this can be reduced to:

```
list => Const(R.head(list)).value
// or
list => R.head(list)
```

And a setter (`R.over`

) would look like:

```
(fn, list) => {
const toFunctor = R.compose(Identity, fn);
return map(newVal => update(0, newVal, list), toFunctor(R.head(list))).value
}
```

and given `map(f, Identity(x)) === Identity(f(x))`

, this can be reduced to:

```
(fn, list) => Identity(update(0, fn(R.head(list)), list)).value
// which is equivalent to
(fn, list) => update(0, fn(R.head(list)), list)
```

and then

`set`

can just be defined in terms of `over`

and `always`

:`const set = (someLens, newVal, thing) => over(someLens, R.always(newVal), thing)`

and that’s enough rambling for now :smile:

Nice explanation, @scott-christopher

I didn’t quite explain anything about how they compose above beyond what I posted in the github issue, but perhaps with the plumbing out of the way I can try explain further.

Suppose we want to create a lens that will focus on the 'id' field of the first element in a list of things.

```
//:: [{ 'id': Number }]
var things = [{ 'id': 0 }, { 'id': 42 }];
```

We could build this by composing `R.lensIndex(0)`

and `R.lensProp('id')`

.

```
var headLens = R.lensIndex(0);
var idLens = R.lensProp('id');
var headIdLens = R.compose(headLens, idLens);
```

We can then see how

`headLens`

and `idLens`

compose by substituting the type variables in the lens signature with those from `things`

and aligning by their common types.```
idLens :: (Number -> f Number) -> ({ 'id': Number } -> f { 'id': Number })
headLens :: ({ 'id': Number } -> f { 'id': Number }) -> ([{ 'id': Number }] -> f [{ 'id': Number }])
headIdLens :: (Number -> f Number) -> ([{ 'id': Number }] -> f [{ 'id': Number }])
```

In terms of how they compose using the plain ol' function

as its argument:

`R.compose`

, you can see that `idLens`

produces a `toFunctor`

`(a -> f a)`

with the same type that `headLens`

acceptsas its argument:

`({ 'id': Number } -> f { 'id': Number })`

This is why function produced by

`headLens`

is composed to the left of `idLens`

using `R.compose`

, because `headLens`

can receive the `toFunctor`

`idLens`

.
`R.view`

or `R.over`

can then pass the initial `Const`

or `Identity`

`toFunctor`

Again, I don’t know whether this helps or not, so please feel free to ask any questions to help clarify.

@scott-christopher thanks for the explanation!

I haven't studied lenses yet so I can't be a million percent sure about this, but it sounds to me like the reason lenses compose "backwards" is very analogous to the reason transducers compose backwards

where

`Const`

or `Identity`

corresponds with the `f`

argument to `transduce`

and the compositions of lenses, eg

`var headIdLens = R.compose(headLens, idLens);`

corresponds to the `xf`

argument to `transduce`

, eg `R.compose(R.map(inc), R.filter(isOdd))`

maybe a small insight into transducers for those who understand lenses better

Yeah, that's part of the big picture: transducers are a less generalized version of lenses