<div dir="ltr">On Sun, Jul 14, 2013 at 7:31 AM, Clark Gaebel <span dir="ltr">&lt;<a href="mailto:cgaebel@uwaterloo.ca" target="_blank">cgaebel@uwaterloo.ca</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p>Similarly, I&#39;ve always used:</p>
<p>import qualified Data.HashSet as S</p>
<p>nub :: Hashable a =&gt; [a] -&gt; [a]<br>
nub = S.toList . S.fromList</p>
<p>And i can&#39;t think of any type which i can&#39;t write a Hashable instance, so this is extremely practical.</p></blockquote><div>This won&#39;t yield results lazily (e.g. nub (repeat &#39;x&#39;) = _|_ instead of &#39;x&#39; : _|_), but Niklas&#39; ordNub will.  His ordNub can be translated directly to HashSet and still have the stability and laziness properties.</div>

<div><br></div><div>A difficulty with putting ordNub in Data.List is that it depends on containers, which is outside of the base package.  Some options:</div><div><br></div><div> * Move the implementation of Set to base.</div>

<div><br></div><div> * Implement a lean version of Set in base that only provides &#39;insert&#39; and &#39;member&#39;.</div><div><br></div><div> * Define ordNub in Data.Set instead.</div><div><br></div><div>Adding a Hashable-based nub to base would be even more problematic, since you&#39;d need Hashable in base.</div>

</div></div></div>