Thanks for all the input! :)<br><br>My current code (unfinished) is here: <a href="http://github.com/jvranish/IndexedCollection/tree/master">http://github.com/jvranish/IndexedCollection/tree/master</a><br>but I think I'll shorten the names as you suggest. (and add some strictness to availableKeys)<br>
<br>I also added an extra phantom type parameter to the collection (and key) so that I can prevent keys from being used on different collections even if they hold elements of the same type. <br><br>There is still problem that trying to use a deleted key might return a bad result rather than an error.<br>
I'm not sure how to fix that one. I could keep another buffer, perhaps of the last 100 or so deleted keys, so that a key doesn't get recycled until 100 other keys have been freed. This would increase the chances of detecting this type of error.<br>
I could also possibly integrate it with Bernie's suggestion, which would probably significantly improve performance in my case. But the added complexity might not be worth it. <br><br>Hmm although... I could potentially do something evil and detect the use of a deleted key via stableNames. I'd rewrap my keys on recycle so that there stablenames change. Then I can check on lookup if the key used has the same stableName as the key in the collection, if they don't match either raise an error or return Nothing. <br>
Not sure if I feel that evil though :D<br><br>Thanks again for the input :)<br><br>- Job<br><br><br><div class="gmail_quote">On Fri, Aug 21, 2009 at 7:26 AM, Heinrich Apfelmus <span dir="ltr"><<a href="mailto:apfelmus@quantentunnel.de">apfelmus@quantentunnel.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">Heinrich Apfelmus wrote:<br>
> Job Vranish wrote:<br>
>> I've been in a situation a lot lately where I need to keep a collection of<br>
>> values, and keep track of them by a persistent index.<br>
>><br>
><br>
</div><div class="im">> module Store (Key, Store, empty, add, delete, lookup) where<br>
><br>
</div><div class="im">> newtype Key = Key { int :: Int }<br>
><br>
</div>> empty :: Store a<br>
> add :: a -> Store a -> (Key, Store a)<br>
<div class="im">> delete :: Key -> Store a -> Store a<br>
</div><div class="im">> lookup :: Key -> Store a -> Maybe a<br>
><br>
</div><div class="im">> This way, the user doesn't know and care how Key is implemented.<br>
><br>
> Last but not least, there is the issue that trying to use an already<br>
> deleted key might yield a wrong result instead of an error. That<br>
> shouldn't happen if used correctly, but might give a headache when<br>
> debugging.<br>
<br>
</div>There is even a very simple way to prevent at least some cases of<br>
misuse, when one key is accidentally used on stores of different type. A<br>
phantom parameter will do the trick:<br>
<br>
newtype Key a = Key { int :: Int }<br>
<br>
add :: a -> Store a -> (Key a , Store a)<br>
delete :: Key a -> Store a -> Store a<br>
lookup :: Key a -> Store a -> Maybe a<br>
<div><div></div><div class="h5"><br>
<br>
<br>
Regards,<br>
apfelmus<br>
<br>
--<br>
<a href="http://apfelmus.nfshost.com" target="_blank">http://apfelmus.nfshost.com</a><br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>