{-# OPTIONS -fglasgow-exts #-}

module Rules where

{-# RULES
"transform/transform" forall (f::forall m. Monoid m => (a -> m) -> (b -> m))
                             (g::forall m. Monoid m => (b -> m) -> (c -> m))
                             (l::FMList Int). transform f (transform g  l) = transform (g.f) l
   #-}

class Monoid where {}

newtype FMList a = FM { unFM :: forall m . Monoid m => (a -> m) -> m }

singleton    :: a -> FMList a
singleton x  = FM $ \f -> f x

foo = transform (. (*2)) (transform (. (+1)) (singleton 10))

bar = mapK (*20) (mapK (+40) (singleton 100))


{-# INLINE mapK #-}
mapK g x = transform (. g) x

{-# NOINLINE transform #-}
transform :: (forall m. Monoid m => (a -> m) -> (b -> m)) -> FMList Int -> FMList Int
transform = error "urk"

