Using lenses

Joseph Abrahamson me
Thu Oct 3 16:35:42 UTC 2013

I rarely use lens without using any Prisms so this is slightly out of
scope, but I absolutely love both lens-aeson and my own package
hexpat-lens for diving deeply into nested data structures. Here's a
line from a toy web scraper I wrote a few weeks ago using hexpat-lens.

    p ^.. _HTML' . to allNodes
                 . traverse . named "a" 
                 . traverse . ix "href" 
                 . filtered isLocal . to trimSpaces

The _HTML' bit is a parser Prism based loosely on lens-aeson's _JSON
Prism and allNodes uses lens' built-in generic traversal
machinery. Specifically, it's a synonym for universe which uses the
Plated instance I wrote since there's an obvious concept of the child
of an XML node. You could do it even more lens-ily by using universeOf
and passing it a traversal into the children. Anyway, that's all the
"extra" stuff used here.

The essence of this code is to dive into all of the anchors in a page,
pull their href (if it exists), remove any non-local hrefs, and then
canonicalize the final string. The (^..) runs the traversal returning
a list of the results.

The clever part I want to share is the use of ix here enabled by the
Ixed instance for UNode which lets me treat the implicit attribute
dictionary using the generic lens machinery.

Also in XML processing, I've begun to look into the bidirectional
programming XML pickler libraries.  I'm not sure which will work best
for me right now, but by writing a few combinators like `xpWrapIso`
I'm able to integrate the entire Iso machinery of lens (of which there
is a lot) to bootstrap the parser/printers I'm writing.

Hopefully this gives a good, if brief, glimpse into some practical
lens usage I've had recently.

? Joseph

More information about the Libraries mailing list