If I write an instance of Monoid
with a horrible complexity for its operation (<>)
, will GHC know that
mempty <> x = x
x <> mempty = x
and avoid computing (<>)
?
I'm also interested in how you got that information, and, if this optimization does not exits, whether this could be done or has been discussed previously.
Here's a sketch for how a rewrite rule can accomplish what you've layed out in your comment:
{-# LANGUAGE UnicodeSyntax #-}
module RewriteMempty where
data Big = Big String
instance Semigroup Big where
Big s <> Big t = Big . reverse $ reverse s++reverse t
instance Monoid Big where
mempty = Big ""
class Inflatable a where
inflate :: a -> Big
instance Inflatable Double where
inflate = Big . show . replicate 100000
{-# NOINLINE poppedBalloon #-}
poppedBalloon :: Big
poppedBalloon = mempty
{-# RULES "OmitPopped" ∀ x . poppedBalloon <> x = x #-}
instance Inflatable Int where
{-# INLINE inflate #-}
inflate _ = poppedBalloon
big :: Big
big = inflate (pi :: Double)
debig :: Big -> String
debig (Big s) = show $ length s
{-# SPECIALIZE busy :: Int -> String #-}
busy :: Inflatable a => a -> String
busy x = debig $ inflate x <> big