I have a large sum type
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
I need a Hashable instance for this datatype. I could of course just type the instance by hand, but fortunately there is a default implementation for hashWithSalt based on generics.
Unfortunately - as far as I understand - this requires any type that can be "packed" inside the Value type to have a Hashable instance. Well, UTCTime does not have one.
So it looks like I can choose between two "suboptimal" solutions:
I think there should be a third, "optimal" way: to only write an implementation for value constructors where there are not possible to do it automatically, i.e do something like this:
instance Hashable Value where
hashWithSalt (VUTCTime t) = ... -- custom implementation
hashWithSalt _ = ... -- use the default implementation
The question of course could be asked more generally: how can I re-use existing instance implementation in case of certain value constructors while having my own implementation in specific cases without having to write boilerplate for each of the value constructors.
For this particular situation, you should just use the hashable-time package, which defines the orphan instance in a standardised place.
In general for this kind of situation, I would either:
newtype
, so you can define the instance locally without risking orphan-instance trouble.newtype
would give).