[Haskell-cafe] How is default method signatures supposed to be used together with Generics

Johan Tibell johan.tibell at gmail.com
Wed Dec 12 05:28:19 CET 2012


Hi,

I noticed that you're not required to export the types mentioned in
the default method signature. For example, you could have:

    default hashWithSalt :: (Generic a, GHashable (Rep a)) => Int -> a -> Int
    hashWithSalt salt = ghashWithSalt salt . from

and not export the GHashable class. However, if users try to define an
instance of Hashable but forget to derive Generic:

    data Foo a = Foo a String
                 deriving (Eq)  -- Oops, forgot Generic here

    instance (Hashable a) => Hashable (Foo a)

they get a pretty bad error message:

Test.hs:10:10:
    Could not deduce (Generic (Foo a),
                      Data.Hashable.Class.GHashable (GHC.Generics.Rep (Foo a)))
      arising from a use of `Data.Hashable.Class.$gdmhashWithSalt'
    from the context (Hashable a)
      bound by the instance declaration at Test.hs:10:10-41
    Possible fix:
      add (Generic (Foo a),
           Data.Hashable.Class.GHashable
             (GHC.Generics.Rep (Foo a))) to the context of
        the instance declaration
      or add instance declarations for
         (Generic (Foo a),
          Data.Hashable.Class.GHashable (GHC.Generics.Rep (Foo a)))
    In the expression: (Data.Hashable.Class.$gdmhashWithSalt)
    In an equation for `hashWithSalt':
        hashWithSalt = (Data.Hashable.Class.$gdmhashWithSalt)
    In the instance declaration for `Hashable (Foo a)'

Exporting GHashable would help a little bit in that users would at
least know what this GHashable class that the error talks about is.

What's best practice?

-- Johan



More information about the Haskell-Cafe mailing list