I'm developing a type constructor class and want the constraint forall a. Monoid (m a) (where m :: * -> *
), which is neither legal Haskell, nor supported by GHC.
As a work-around, I used the first encoding suggested in "Simulating Quantified Class Constraints" (Valery Trifonov, Haskell Workshop '03). Add a type class
class Monoid_f m where
mempty_f :: forall a. m a
mappend_f :: forall a. m a -> m a -> m a
and an instance *schema*
-- instance Monoid_f f where { mempty_f = mempty ; mappend_f = mappend }
to instantiate manually wherever necessary. For instance,
instance Monoid_f [] where { mempty_f = mempty ; mappend_f = mappend }
The paper's second approach is to replace the schema and multiple instantiations with a single instance.
instance Monoid_f f => Monoid (f a) where
{ mempty = mempty_f ; mappend = mappend_f }
As the paper points out,
Unfortunately, due to the type variable f in the head of the instance type, this declaration is not in Haskell 98; however, at least two implementations support extensions allowing such declarations.