Как указать экземпляр класса типов?

У меня есть (вполне) законный случай, когда есть две реализации экземпляра типа, и я хочу указать вариант по умолчанию. Заметив, что выполнение модульной арифметики с типами Int привело к множеству коллизий хешей, я хочу попробовать GHC's Int64. У меня есть следующий код:

class Hashable64 a where
    hash64 :: a -> Int64

instance Hashable64 a => Hashable a where
    hash = fromInteger . toInteger . hash64

instance Hashable64 a => Hashable64 [a] where
    hash64 = foldl1 (\x y -> x + 22636946317 * y) . map hash64

и экземпляр Hashable64 Char ,что, таким образом, приводит к двум реализациям для Hashable String , а именно:

  • Та, которая определена в Data.Hashable .
  • Отмечено, что это Hashable64 например, затем преобразование в обычный Int для экземпляра Data.Hashable .

Второй путь кода может быть лучше, потому что он выполняет хеширование с Int64 с. Могу ли я указать использование этого производного экземпляра Hashable String ?

Редактировать 1

Извините, я забыл добавить, что уже пробовал использовать перекрывающиеся экземпляры; возможно я просто не правильно реализую? В документации по перекрывающимся экземплярам говорится, что это работает, когда один экземпляр более конкретен. Но когда я пытаюсь добавить конкретный экземпляр для Hashable String , ситуация не улучшается. Полный код на [ http://pastebin.com/9fP6LUX2 ] (извините за лишний заголовок по умолчанию).

instance Hashable String where
    hash x = hash (hash64 x)

Я получаю

Matching instances:
  instance (Hashable a) => Hashable [a] -- Defined in Data.Hashable
  instance [overlap ok] Hashable String
    -- Defined at Hashable64.hs:70:9-23

Edit 2

Любые другие решения этой конкретной проблемы: добро пожаловать. Хорошее решение может дать представление об этой проблеме перекрывающихся экземпляров.

5
задан Micha Wiedenmann 19 September 2019 в 07:01
поделиться