Skip to content

Simplifying the Hashable instance for TDCtx. #2603

@jonathanknowles

Description

@jonathanknowles

The TDCtx type currently has a manually-defined Hashable instance:

-- Need to write manual Hashable instance since MonoidMap
-- does not have instances of its own.
instance Hashable TDCtx where
hashWithSalt s (TDCtx ctx versions) =
s
`hashWithSalt` ctx
`hashWithSalt` (getSum <$> MM.toMap versions)

The release of monoidmap-hashable should make it possible to auto-derive this instance.

However, it turns out that Data.Semigroup.Sum is not (yet!) an instance of Hashable. (See haskell-unordered-containers/hashable#326.)

This means we still need to do a bit of work to auto-derive the Hashable instance for TDCtx.

Potential workarounds

I can think of two workarounds (until hashable is upgraded):

  1. Define an orphan instance of Hashable for Sum. Of course, an orphan instance is not ideal. However, if the hashable package is eventually upgraded to provide such an instance, this would lead to a compile error for our orphan instance, prompting us to remove the instance, which is actually what we want.

  2. Define a custom TDVersionSum type, analogous to Sum, but with a Hashable instance. Then we could write:

    data TDCtx = TDCtx
      { getTDCtx :: Ctx TDVar TydefInfo
      , getTDVersions :: MonoidMap Text (TDVersionSum Int)
      }
      deriving (Eq, Generic, Hashable, Show, ToJSON)
    
    newtype TDVersionSum a = TDVersionSum {getTDVersionSum :: a}
      deriving (Eq, Generic, Hashable, Show, ToJSON)
      deriving (Num, Semigroup, Monoid, MonoidNull) via Sum a

However, option 2 has the disadvantage that the compiler would not automatically notify us if the hashable package is eventually upgraded so that Sum becomes an instance of Hashable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions