<blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">but if it were a choice between findMax and<br>
extractWithKey with some Applicative and Monoid and whatever else<br>
magic, I&#39;d use findMax every time :) I&#39;d be wary of putting anything<br>
difficult to describe in a default interface for a basic data type.<br clear="all"></blockquote><div><br>Okay, some restatement required here: I&#39;m suggesting this method <i>only</i> for Data.Map and Data.IntMap -- not for anything more common -- and I&#39;m not by any means suggesting that I&#39;d use this in every case over findMin, but merely using findMin as an example application.  I <i>do</i> think it&#39;s okay for a commonly used module to have some advanced methods for advanced users.<br>

 <br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">And of course creating, inserting, updating, and deleting.  Rarely key<br>
and value mapping.  Any interface that provides those 9 functions will<br>
satisfy all needs I can think of.  If they can all be implemented with<br>
extractWithKey, then great, put that in the class interface and define<br>
the rest with defaulting methods.<br></blockquote><br>Quite honestly, I use key and value mapping all the time, in most applications I need maps for, and extractWithKey generalizes (and makes more efficient) several applications use regularly.<br>

<br>Here&#39;s one more example of an application that can&#39;t be done nicely or efficiently with application of the currently existing methods:<br><br>extractMinPair :: Map k1 (Map k2 v) -&gt; Maybe (((k1, k2), v), Map k1 (Map k2 v))<br>

extractMinPair m = do<br>   ((k1, m1), m&#39;) &lt;- minViewWithKey m<br>   ((k2, v), m1&#39;) &lt;- minViewWithKey m1<br>   return (((k1, k2), v), if null m1&#39; then m&#39; else insert k1 m1&#39; m)<br><br>(In particular, this is the extractMin implementation from the generalized trie on keys of type (k1, k2), which motivated the method in the first place.)<br>

<br>Note that in most cases, we&#39;ll need to insert m1&#39; back into m, which is really ugly, and definitely destroys the nicer recursive properties that I&#39;m looking for.  Rather, if I can extract information and modify a value from the map with a single use of extractWithKey,<br>

<br>extractMinPair m = getFirst $ extractWithKey (\ k1 m1 -&gt; fmap (\ ((k2, v), m1&#39;) -&gt; (((k1, k2), v), guardNull m1&#39;)) (minViewWithKey m1)) m<br>   where guardNull m = if null m then Nothing else Just m<br>
<br>
In the list of methods you named as particularly critical, you talked about creating, inserting, updating, and deleting; you actually didn&#39;t mention looking up values, which I assume you meant to -- since what&#39;s the point of the map if you can&#39;t look up any values?  extractWithKey is useful when I want to look up a value, and edit it, at the same time, without an exra O(log n) pass, and it specifically and elegantly takes care of the case where we want to simultaneously look up and edit the minimum or maximum value of a map.<br>

<br></div>Louis Wasserman<br><a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a><br><a href="http://profiles.google.com/wasserman.louis">http://profiles.google.com/wasserman.louis</a><br>