I'm trying this (for learning purposes):
{-# LANGUAGE FlexibleInstances #-}
instance Monoid (a -> a) where
mempty = id
mappend f g = f . g
expecting id <> id
to be equal to id . id
However, with (id <> id) 1
I receive this error:
Non type-variable argument in the constraint: Monoid (a -> a)
What should I change to run it?
It's just to understand monoids and Haskell typeclasses better, not for any practical usage.
This will need {-# OVERLAPPING #-}
pragma since GHC.Base has an instance for Monoid (a -> b)
when b is a Monoid:
{-# LANGUAGE FlexibleInstances #-}
import Data.Monoid (Monoid, mempty, mappend, (<>))
instance {-# OVERLAPPING #-} Monoid (a -> a) where
mempty = id
mappend f g = f . g
then, above instance will be invoked for a -> a
, even if a
is a Monoid:
\> (id <> id) 1
1
\> (id <> id) [1]
[1]
whereas with Monoid b => a -> b
the instance from GHC.Base will be invoked:
\> ((:[]) <> (:[])) 1
[1,1]
Note that Data.Monoid
provides an exact same instance as yours for a -> a
but there the overlap is bypassed using newtype Endo a
.