Есть ли в Haskell универсальный класс типов Hashable? (он же "производный (Hashable)")
Кто-нибудь написал общую функцию, чтобы hash
функции могут быть созданы автоматически для пользовательских типов данных (используя deriving
механизм)? Несколько раз я писал следующий пример,
data LeafExpr = Var Name | Star deriving (Eq, Show)
instance Hashable LeafExpr where
hash (Var name) = 476743 * hash name
hash Star = 152857
Это может быть сгенерировано автоматически: основная идея заключается в том, что при добавлении данных вы умножаете на простое число, например, со списками,
hash (x:xs) = hash x + 193847 * hash xs
По сути, я хотел бы написать
data LeafExpr = ... deriving (Hashable)
Редактировать 1
Спасибо всем за очень полезные ответы, всем. Я постараюсь добавить общий метод в качестве упражнения, когда у меня будет время. Пока (возможно, что имел в виду sclv?) Я понял, что могу написать немного лучший код,
instance Hashable LeafExpr where
hash (Var name) = hash ("Leaf-Var", name)
hash Star = hash "Leaf-Star"
Редактировать 2
Используя ghc, умножение на случайные простые числа работает намного лучше, чем кортеж в редактировании 1. Конфликты с Data.HashTable сократились с 95% (очень плохо) до 36%. Код здесь: [ http://pastebin.com/WD0Xp0T1 ] [ http://pastebin.com/Nd6cBy6G ].
1 ответ
Сколько скорости вам нужно? Вы можете использовать один из пакетов, которые используют шаблон haskell для генерации кода сериализации, чтобы преобразовать значение в двоичное, а затем хэшировать двоичный массив с помощью hashable.