Endofunction as Monoid

前端 未结 2 674
南笙
南笙 2021-01-14 02:52

I\'m trying this (for learning purposes):

{-# LANGUAGE FlexibleInstances #-}

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


        
2条回答
  •  梦毁少年i
    2021-01-14 03:30

    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.

提交回复
热议问题