Генерация уникальных, сопоставимых значений

Каков хороший способ генерировать специальные ключи, где каждый ключ уникален для программы? В идеале, действие вида:

newKey :: IO Key

такое, что:

do a <- newKey
   b <- newKey
   return (a == b)

всегда возвращает false. Также должна быть возможность использовать Key в эффективном ассоциативном контейнере (например, Map).

Это можно использовать, например, для поддержания коллекции обработчиков событий, поддерживающих случайную вставку и удаление:

Map Key EventHandler

Варианты, о которых я знаю:

  • newIORef(): Удовлетворяет инварианту выше, но IORef не имеет экземпляра Ord.

  • malloc: Быстро, и Ptr () имеет экземпляр Ord, но результат не собирается в мусор.

  • newStablePtr(): Не собран мусор, и StablePtr не имеет экземпляра Ord.

  • newIORef() >>=makeStableName: Должен удовлетворять приведенному выше инварианту и собирает мусор, но более сложен в использовании (требует от меня использования хэш-таблицы).

  • mallocForeignPtrBytes1: Удовлетворяет обоим критериям, но эффективно ли это?

mallocForeignPtrBytes1 кажется мне лучшим вариантом. Полагаю, я мог бы сделать его немного более эффективным, используя непосредственно примоп newPinnedByteArray# от GHC.

Есть ли лучшие варианты? Является ли подход mallocForeignPtrBytes ущербным по какой-то неочевидной причине?

11
задан Joey Adams 24 December 2011 в 06:05
поделиться