a place I put stuff

Lenses 101 (for me)

Posted on April 30, 2014

Note: This is a short commentary on the new wreq library. These comments were directed at my coworkers, but I thought they’d be interesting here. This post is literate Haskell, you should be able to cut-n-paste.

I think a big reason why I’m so stoked about this is that it’s a solid library that’s offering a lens-based API (something that I think will show up more and more as time goes on). I’m still digging into them, but lenses are sort of like the “.” (dot) from Ruby, but implemented as a library and infinitely more flexible:


your basic “getter” is ^. (carrot-dot, aka “view”) It lets you “view” things:

And using it to view inside the Person datatype:

Next you’ve got your “setter” (it just updates, non-destructively returning a new thing), also called “set”:

or saying it with operators (the & above is reverse function application, the function on the right is applied to the data on the left, kinda like a shell pipeline):

“But Chris!” you interject, “that’s just lame-o ‘.’ that’s in Ruby ALREADY! Show me some lazer-beam stuff!” Okay, lenses also do traversing! That is you can get/set a bunch of things at once:

Now we traverse over the employees field of the Bendyworks structure, and we can compose a getter with that!

The thing that’s kinda cool is that “employees.traversed.fn” forms a sort-of lens on the whole Bendyworks datatype, letting us walk over it and pull out values. The traversal is a first-class thing (those ’.’s in the name are just plain-old function composition!). We can store it and use it as a new accessor:

They’re really composable! You can set a traversal with your old friend .~ (set):

That’s simultaneously setting the emails of all Bendyworkers to the string “[HIDDEN]”. Notice how, if you squint, it’s like the .~ is a SUPER-DOT that can set a bunch of stuff at once. I think it is way cool. I’m just starting to look at the lens library and it’s big. There are tons of functions in there and a lot ground covered. But I think that as time goes on this will become pretty common. Functional getters and setters FTW!