<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">There is a list of problems with the current "Map" and "IntMap" modification interfaces:<br><br>&nbsp;&nbsp;&nbsp;- they are filled with quirky and too specialized functions<br><br>&nbsp;&nbsp;&nbsp;- they are not consistent in terms of how equally named functions behave:&nbsp;<a href="http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-IntMap-Strict.html#v:updateLookupWithKey">http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-IntMap-Strict.html#v:updateLookupWithKey</a><br><br>&nbsp;&nbsp;&nbsp;- they still don't cover some important scenarios of use<br><br>Because of the above I have very often found myself in requirement for the following function:<br><br>&nbsp;&nbsp;&nbsp;withItem ::<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Ord k) =&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k -&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Maybe i -&gt; (r, Maybe i)) -&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map k i -&gt; (r, Map k i)<br>&nbsp;&nbsp;&nbsp;withItem k f m =&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item = Map.lookup k m<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(r, item') = f item<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m' = Map.update (const item') k m<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in (r, m')<br><br>It covers all the imaginable scenarios of modification operations: delete, update, replace, - yet it also provides one with ability to extract the modified data and not only. The problem is that this implementation involves a repeated lookup for the same item: first with "lookup", then with "update" - but the "containers" library exposes no functionality to get around that. So I suggest to implement an efficient version of "withItem" in the library.<br><br>This function turns out to be far more generalized than any of the currently present in the library, so it can become a basic building block for all sorts of modifying functions, including all the already existing ones, e.g.:<br><br>&nbsp;&nbsp;&nbsp;alter :: Ord k =&gt; (Maybe a -&gt; Maybe a) -&gt; k -&gt; Map k a -&gt; Map k a<br>&nbsp;&nbsp;&nbsp;alter f k = snd . withItem k (\i -&gt; ((), f i))<br><br>&nbsp;&nbsp;&nbsp;delete :: Ord k =&gt; k -&gt; Map k a -&gt; Map k a<br>&nbsp;&nbsp;&nbsp;delete k = snd . withItem k (const ((), Nothing))<br><br>&nbsp;&nbsp;&nbsp;updateLookupWithKey ::&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Ord k) =&gt;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(k -&gt; a -&gt; Maybe a) -&gt;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k -&gt;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map k a -&gt; (Maybe a, Map k a)<br>&nbsp;&nbsp;&nbsp;updateLookupWithKey f k =&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;withItem k $ \i -&gt; case i of<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Just i -&gt; case f k i of<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nothing -&gt; (Just i, Nothing)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Just i' -&gt; (Just i', Just i')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ -&gt; (Nothing, Nothing)<br><br>You can see how easy it makes to achieve any sort of specialized functionality. So, besides the evident benefits, this function can also become a replacement for a whole list of confusing specialized ones, thus greatly lightening the library.<br><br>You might have also noticed how this function is based around the standard "a -&gt; (b, a)" pattern of the "State" monad, thus making it easily composable with it using the "state" and "runState" functions.<br><br>Summarizing, my suggestions are:<br><br>&nbsp;&nbsp;&nbsp;1. Implement an efficient version of "withItem" for lazy and strict versions of "Map" and "IntMap".<br><br>&nbsp;&nbsp;&nbsp;2. Change the order of parameters from "lambda -&gt; key" to "key -&gt; lambda". The "updateLookupWithKey" example implementation shows how this change can be benefitial.<br><br>&nbsp;&nbsp;&nbsp;3. Begin the deprecation process of the following functions: insertWith, insertWithKey, insertLookupWithKey, adjust, adjustWithKey, update, updateWithKey, updateLookupWithKey, alter.<br><br>A deadline for discussion is set to 6 weeks.<br><br>For a formatted version of this message please visit&nbsp;<a href="https://github.com/haskell/containers/issues/28">https://github.com/haskell/containers/issues/28</a>.<br></body></html>