In the meantime, to refocus attention on the original proposal.... ;)<div><br></div><div>For the moment, if only because it's currently the more standard approach, I'll concede and use the foldr/build approach.</div>
<div><br></div><div><div>{-# INLINE [0] pairCons #-}</div><div>pairCons :: ((a, b) -> c -> c) -> a -> b -> c -> c</div><div>pairCons = curry</div><div><br></div><div>{-# RULES</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>"Data.Map.toAscList->build" [~1] toAscList = \ m -> GHC.build </div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>(\ c n -> foldrWithKey (pairCons c) n m);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>#-}</div></div><div><br></div><div>Since the normal definition of toAscList is just foldrWithKey (curry (:)) [], there's no need to rewrite it back to toAscList.</div>
<div><br></div><div>A few possible additional modifications:</div><div><ul><li>Pull a similar trick for toDescList. It's not as if it'd be all that difficult...</li><li>Reimplement the (==) and compare functions for Data.Map as follows:</li>
</ul><div>m1 == m2 = size m1 == size m2 && and (zipWith (==) (toAscList m1) (toAscList m2))</div></div><div>m1 `compare` m2 = foldr mappend (compare (size m1) (size m2)) (zipWith compare (toAscList m1) (toAscList m2))</div>
<div><br></div><div>which gets some deforesting.</div><div><br></div><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>
</div>