<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><p style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;margin-top:0px">Hello!</p><p style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;margin-top:0px">In some recent analysis I ran into a subtlety that caught me by surprise: Data.Map.mapKeysMonotonic has a misleading name.</p><p style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;margin-top:0px">A monotonic function is not a strictly <em style="box-sizing:border-box">increasing</em> function, but merely non-decreasing. However, <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:11.9px;background-color:rgba(27,31,35,0.05);border-radius:3px;margin:0px;padding:0.2em 0.4em">mapKeysMonotonic</code> requires that it's mapping function be injective, which means it really only supports <em style="box-sizing:border-box">increasing</em> functions.</p><div class="gmail-highlight gmail-highlight-source-haskell" style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;overflow:visible"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:11.9px;margin-bottom:0px;margin-top:0px;background-color:rgb(246,248,250);border-radius:3px;line-height:1.45;overflow:auto;padding:16px;word-break:normal">valid (mapKeysMonotonic (<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">\</span>x <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">if</span> x <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">`elem`</span> [<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">1</span>,<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2</span>] <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">then</span> <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">else</span> x) (fromList [(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">1</span>, <span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>a<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>), (<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2</span>, <span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>b<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>), (<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">3</span>, <span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>c<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>)])) <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">==</span> <span class="gmail-pl-ent" style="box-sizing:border-box;color:rgb(34,134,58)"><span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">False</span></span></pre></div><p style="box-sizing:border-box;margin-bottom:16px;margin-top:0px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px">The docs hint at this with "This means that <a class="gmail-user-mention" href="https://github.com/f" style="box-sizing:border-box;background-color:transparent;color:rgb(36,41,46);text-decoration-line:none;font-weight:600;white-space:nowrap">@f</a>@ maps distinct original keys to distinct resulting keys."</p><p style="box-sizing:border-box;margin-top:0px;color:rgb(36,41,46);font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;margin-bottom:0px">However, I'd propose that we deprecate this name and rename to something like <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:11.9px;background-color:rgba(27,31,35,0.05);border-radius:3px;margin:0px;padding:0.2em 0.4em">mapKeysIncreasing</code>or <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:11.9px;background-color:rgba(27,31,35,0.05);border-radius:3px;margin:0px;padding:0.2em 0.4em">mapKeysAsc</code> (to follow the pattern of other *Asc functions). We should also clarify the docs.</p></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">From <a href="https://github.com/haskell/containers/issues/617">https://github.com/haskell/containers/issues/617</a><br></div></div>