У меня большая сумма типа
data Value
= VNull
| VDouble !Double
| VSci !Scientific
| VInt !Int
| VText !Text
| VTexts ![Text]
| VByteString !BS.ByteString
| VUTCTime !UTCTime
-- This goes on for quite a few more lines
Мне нужен экземпляр Hashable для этого типа данных. Конечно, я мог бы просто напечатать экземпляр вручную, но, к счастью, для hashWithSalt существует реализация по умолчанию, основанная на обобщениях.
К сожалению - насколько я понимаю - для этого требуется любой тип, который может быть "упакован" внутри типа Value, чтобы иметь экземпляр Hashable. Ну, у UTCTime его нет.
Похоже, я могу выбирать между двумя "неоптимальными" решениями:
- Введите экземпляр Hashable от руки.
- Напишите потерянный экземпляр Hashable UTCTime
Я думаю, что должен быть третьим, "оптимальным" способом: писать реализацию только для конструкторов значений, где нет возможности сделать это автоматически, т.е. сделать что-то вроде этого:
instance Hashable Value where
hashWithSalt (VUTCTime t) = ... -- custom implementation
hashWithSalt _ = ... -- use the default implementation
Конечно, вопрос можно задать более широко: как я могу повторно использовать существующую реализацию экземпляра в случае определенных конструкторов значений, в то же время имея собственную реализацию в определенных случаях без необходимости писать шаблон для каждого из конструкторов значений .