data StableNamea
Стабильные имена имеют следующее свойство: Если sn1::StableName и sn2::StableName и sn1 == sn2, то sn1 и sn2 были созданы вызовами makeStableName для одного и того же объекта.
Обратное не обязательно верно: если два стабильных имени не равны, то объекты, которые они называют, все же могут быть равными.
realUnsafePtrEquality#:: a -> a -> Int#
realUnsafePtrEquality# возвращает, являются ли два объекта в куче GHC одним и тем же объектом. Это действительно небезопасно, потому что сборщик мусора перемещает вещи, закрывает и т. д.Насколько мне известно, он может возвращать ложные отрицательные значения (говорят, что два объекта не одинаковы, но это так), но не ложные срабатывания (говорят, что они одинаковы, когда это не так).
Оба они, кажется, делают одну и ту же основную вещь: они могут сказать вам, являются ли два объекта определенно одними и теми же, но не могут ли они определенно не быть.
Я вижу преимущества StableNames:
Преимущества, которые я вижу для realUnsafePtrEquality#:
Мои вопросы:
Я ничего не пропустил?
Есть ли какой-либо вариант использования, в котором тот факт, что StableNames отделены от объектов, которые они называют, является преимуществом?
Является ли один из них более точным (с меньшей вероятностью даст ложноотрицательный результат), чем другой?
Если вам не нужно хэширование, вы не заботитесь о переносимости и вас не беспокоит использование чего-то под названием realUnsafe, есть ли какая-то причина предпочесть StableNames, а не realUnsafePtrEquality#?