I recently ran into the problem of fclabels partial lenses being partial in both directions. This was not a critical problem, but it was annoying that a type had to be Maybe when the code would never use the “Nothing” constructor. There’s a new, interesting lens library called YALL, that inspired me to think about it a bit more. There are some potential issues with this perspective – it is no longer clear that there are algebraic laws that hold. I think that there’s a possibility that this might be resolved by adding some restrictions on the relationship between **m** and **w**. Anyway, the point is that lens library design is not a settled issue.

I’m interested in trying another way of using template haskell to express lenses:

fstLens = [mkLens| \(a, _) -> a |] sndLens = [mkLens| \(_, b) -> b |] fooLens = [mkLens| \(Just (a, b)) -> [a, b] |] tupListIso = [mkIso| \(a, b) = [a, b] |]

Each lens is specified in terms of the implementation of its **get**. We can do this because construction literals are bidirectional – they can be used for pattern matching. The right hand side of the lenses need to have variables in every position in order to preserve the lens laws (otherwise a portion of the **set** would not be reflected in the corresponding **get**).

The partiality of the lenses depends on whether any of the types used have multiple constructors – whether a match could fail. If the constructor on the left could fail, then the lens is partial in both directions (so **fooLens** is fully partial). If the constructor on the right could fail, then the lens is at least partial in the setter.

We can also bring in function application:

plusOneLens = lens (+1) (const . subtract 1) switchPlus = [mkLens| \(a, b) -> (plusOneLens b, plusOneLens a) |]

This is moving towards a full-blown embedded language for creating bidirectional transformations! It’d be interesting to target the feature set of the Boomerang project, which has a particular focus on doing bidirectional operations with text, and can do so with regexes as well as more powerful grammars. I’ve already written a TH quasi-quoter that allows you to use regular expressions in patterns and expressions: rex. Incorporating this into lens generation, by adding cannonical serialization to regexes, would be really cool.

I think that this way of working with lenses / isos would really help to popularize their use in Haskell. While fclabels is quite excellent, the Applicative instance is not a very clear way to construct lenses on compound structures. This is even nice for the typical lenses, as it avoids using typical records in the first place. Though, **foobar_** can be nicer than **get foobar**.