Skip to content(if available)orjump to list(if available)

Lens: Lenses, Folds and Traversals

kccqzy

My biggest piece of advice for people using lenses is to ditch all the operators. Things like ^. or ^.. or ^? or ^@.. or even <<|>~ are all real operators. Yet they look like line noise. Nobody fully remembers them anyways. Just ditch all operators. Use named functions. The function toListOf is immediately clear what it's doing (that it takes a structure and a fold to convert to a list) but ^.. is not.

In general I avoid all custom operators and only use operators that are in packages preinstalled by the compiler (basically just base and containers).

chowells

I strongly recommend using the lens operators. They are uniformly named such that you can trivially identify their behavior based on their lexical construction, and using them reduces mental parsing overhead significantly.

For the former assertion: ^. means "get a single result". ^.. means "get multiple results". ^? means "get zero or one result". ^@.. means "get multiple results, along with their indices". <<|>~ means "modify a value by combining the target with the |> operator from Snoc, then return a tuple of the old target value and the full structure including the combined value". There is a tiny language in the pattern of operator names, and it's worth the 3 minutes of work it takes to learn it.

And as a reward for learning it, you get to write expressions with far fewer parentheses. This is a massive win. Parenthesized expressions introduce a miserable minigame during reading, where you have to properly match each paren to its correct partner keeping a mental stack to handle nesting. By contrast, the lens operators give you the far simpler mental parsing task of separating the optic, the input, and the operation on the input. There's no nesting involved. The process is a simple visual scan that doesn't require keeping a mental stack. It's a lot easier to quickly read and comprehend.

About the only thing you lose is the ability to easily read code out loud. I don't limit myself to thinking in sounds, but I guess for some people it's important to communicate code out loud. For those kinds of pedagogical purposes, I guess it's ok to pass on the operators. But for code I'm going to work with over a long period of time I'd much rather have the readability advantages of the operators.

kqr

I agree strongly with this and take it one step further: I avoid the infix backticks that turn functions `into` operators.

But I'm not a hardliner. I do use backticks sometimes when building joins with Esqueleto and I do use a limited set of lens operators, like ^. and sometimes the %= variants if the situation calls for it.

amelius

Maybe a text-editor should allow the user to look at source code through different "lenses" (pun intended) and show the meanings of symbols whenever the user wants to see them.

ashton314

Emacs (of course) has `prettify-symbols-mode` which lets you describe symbols (eg lambda) and replacement characters (eg λ); the effect is purely in the display system—the underlying buffer does not get modified.

eigenspace

Julia actually has a very nice implementation of lenses in the Accessors.jl package: https://juliaobjects.github.io/Accessors.jl/dev/

I find it to be a lot more comprehensible and transparent than the Haskell version.

moomin

Let’s just say that if you wanted to understand lenses, this is not where you should start; and if you wanted to move to more advanced scenarios, I wouldn’t start here either.

xtoilette

where would you start?

wk_end

Assuming you've got experience with Javascript, read the "Motivation" section on the monocle-ts website:

https://gcanti.github.io/monocle-ts/

null

[deleted]

ohdeargodno

A first good step is getting rid of Haskell's obscure and impenetrable syntax, and checking implementations that would be more readable.

Kotlin's Arrow library hits a good middle ground between FP wizardry and readability, and their documentation on lenses are understandable for the average person: https://arrow-kt.io/learn/immutable-data/lens/ / https://arrow-kt.io/learn/immutable-data/intro/

epgui

> Haskell's obscure and impenetrable syntax

Uhhh... Haskell syntax is simpler than python's or javascript's. It's neither obscure nor impenetrable, but it sounds like it's different than what you're used to.

haskman

If you are looking for a more accessible introduction to lenses, this guide to optics in PureScript is great (and PureScript is basically Haskell). https://thomashoneyman.com/articles/practical-profunctor-len...