Search code examples
haskellhaskell-lens

Lenses: Composing backwards and (.) in Lens context


I have been reading this article and in one of their section it is stated:

Lenses compose backwards. Can't we make (.) behave like functions?

You're right, we could. We don't for various reasons, but the intuition is right. Lenses should combine just like functions. One thing that's important about that is id can either pre- or post- compose with any lens without affecting it.

What does that mean by Lenses compose backwards ?

Also, what does this mean: Can't we make (.) behave like functions ?

(.) is a function and by using it with Lens does it make (.) to behave like something else ?


Solution

  • You could think of the Getter part of a lens as a function, which you can extract using view. For example, the lens way of writing the fst function is:

    view _1 :: (a,b) -> a
    

    Now observe:

    view _1 . view _2 :: (c, (a,b)) -> a  -- First take the second pair element, then the first 
    view (_1 . _2)    :: ((b,a) ,c) -> a   -- This is "backwards" (exactly the opposite order of the above)
    

    For lenses, (.) doesn't behave like it would for functions. For functions, f . g means "first apply g, then f", but for lenses, it means first use the lens f, then use the lens g. Actually, the (.) function is the same for both types, but lens' types make it seem like it's backwards.