ekmett/lens — pull request #325 by nikita-volkov (2013-08-13 18:22:07+00:00)
Title: "atM" for containers of monoidic values

The docs explain the purpose well:

A version of 'at' for containers over monoidic values, which operates on the
values themselves instead of them wrapped in a 'Maybe'.

>>> IntMap.fromList [(1, IntSet.fromList [1,2,3])] ^. atM 1
fromList [1,2,3]

>>> IntMap.fromList [(1, IntSet.fromList [1,2,3])] ^. atM 2
fromList []

Besides removing the redundant wrapper this also greatly simplifies the insertion
of nested values:

>>> IntMap.fromList [(1, IntSet.fromList [1,2,3])] & atM 2 . contains 4 .~ True
fromList [(1,fromList [1,2,3]),(2,fromList [4])]

And makes the deletion cleaner:

>>> IntMap.fromList [(1, IntSet.fromList [1,2,3]), (2, IntSet.fromList [4])] & atM 2 . contains 4 .~ False
fromList [(1,fromList [1,2,3])]

IMO the function could be relocated to the "At" class with a default-signature implementation based on the standard "at". This way all the already existing instances of "At" will get this function for free. But my expertise in the library was not enough to implement it this way, so it would be super nice if someone approached the issue, although a requirement for that is debatable, so it's also open for discussion.

Any way, this pull request already contains an implementation in a separate type class with instances for `Map`, `IntMap` and `HashMap`.