We regularly need to construct records full of default values from a row of field names in our application. If any type has a Monoid instance, it’s good to go – we’ll use mempty. However, if a type doesn’t, then it’ll require an instance of the Default type class to produce a default value.
A simple version of the class is below: it has one implementation, def, which simply provides a value. I then created an instance for monoids, stating that any value with a monoid instance should defer to its mempty value.
class Default v where
def :: v
instance defaultMonoid :: Monoid v => Default v where
def = mempty
data Summer = Winter | Fall
instance defaultSummer :: Default Summer where
def = Winter
mkDefault :: forall v. Default v => v
mkDefault = def
x = mkDefault :: Summer
While the class type checks fine, as soon as I define a Default instance for something that is not a monoid, I get a type error. It seems that every instance of Default is expected to be a monoid now, which I didn’t intend.
No type class instance was found for Data.Monoid.Monoid Summer while checking that type forall v. Default v => v is at least as general as type Summer while checking that mkDefault has type Summer in value declaration x
I’m assuming there’s something going on with potential overlapping instances (what if I define Default for a monoid that isn’t the same as the monoid instance?), but I’m curious what exactly this error is about.
If I want to implement this class, will I need to define Default directly for every type without being able to wholesale defer to Monoid?