Search code examples
haskellfunctional-programmingcategory-theorymonoids

Set of transformations f::a->a form a monoid over function composition - how do I make this an instance of Monoid?


It looks as though transformations should form a Monoid, with the identity function as the empty element and standard function composition as the binary operation. I don't think it's particularly useful, but it should be possible. Something along the lines of:

instance Monoid (a -> a) where
        mempty = id
        mappend f g = (.)

The above doesn't compile, possibly because it is masked by the pre-existing definition

instance Monoid b => Monoid (a -> b) where
    mempty _ = mempty
    mappend f g x = f x `mappend` g x

Error is:

Illegal instance declaration for ‘Monoid (a -> a)’
      (All instance types must be of the form (T a1 ... an)
       where a1 ... an are *distinct type variables*,
       and each type variable appears at most once in the instance head.
       Use FlexibleInstances if you want to disable this.)
    In the instance declaration for ‘Monoid (a -> a)’

I'm still a Haskell scrub so I'm not sure how I can fix this - any help?


Solution

  • Actually the error message describes it quite well: a -> a is a too specific type:

    All instance types must be of the form (T a1 ... an) where a1 ... an are distinct type variables, and each type variable appears at most once in the instance head.

    The T here is the function type ->, you could've written without the special infix notation

    instance Monoid ((->) a a) where …
    

    and clearly a doesn't appear only once.

    On how to can fix this, again the error message recommends

    Use FlexibleInstances if you want to disable this [restriction].