问题
I have a body of code that uses a monad to abstract whether the actual implementation runs inside ST or IO. Removing the extra layer of abstraction and just substituting concrete types gives a huge speedup (~4.5x) due to the inlining and missing typeclass function call overhead. I was thinking of getting some of that performance by using a specialize pragma, but I'm getting a rather meaningless warning from the compiler. I can't make a simple reproduction case as the simple example seems to work, and I don't know what's causing the difference in my actual program.
Basically, my program does this:
{-# LANGUAGE FlexibleInstances, RankNTypes #-}
module STImpl (runAbstractST, MonadAbstractIOST(..), ReaderST) where
import Control.Monad.Reader
import Control.Monad.ST
class Monad m => MonadAbstractIOST m where
addstuff :: Int -> m Int
type ReaderST s = ReaderT (Int) (ST s)
instance MonadAbstractIOST (ReaderST s) where
addstuff a = return . (a +) =<< ask
runAbstractST :: (forall s. ReaderST s a) -> a
runAbstractST f = runST $ runReaderT f 99
and
module Main (main) where
import STImpl
import Control.Monad
{-# SPECIALIZE INLINE useAbstractMonad :: ReaderST s Int #-}
useAbstractMonad :: MonadAbstractIOST m => m Int
useAbstractMonad = foldM (\a b -> a `seq` return . (a +) =<< (addstuff b)) 0 [1..50000000]
main :: IO ()
main = do
let st = runAbstractST useAbstractMonad
putStrLn . show $ st
Now, here everything seems to work fine. But in my program I get
RULE left-hand side too complicated to desugar
let {
$dFunctor :: Functor (RSTSim s)
[LclId]
$dFunctor =
Control.Monad.Trans.Reader.$fFunctorReaderT
@ (MonadSim.SimState s)
@ (GHC.ST.ST s)
(GHC.ST.$fFunctorST @ s) } in
simulate
@ (Control.Monad.Trans.Reader.ReaderT
(MonadSim.SimState s) (GHC.ST.ST s))
(MonadSim.$fMonadSimReaderT
@ s
$dFunctor
(Control.Monad.Trans.Reader.$fMonadReaderT
@ (MonadSim.SimState s)
@ (GHC.ST.ST s)
(GHC.ST.$fMonadST @ s))
(Control.Monad.Trans.Reader.$fApplicativeReaderT
@ (MonadSim.SimState s)
@ (GHC.ST.ST s)
$dFunctor
(Control.Applicative.$fApplicativeST0
@ s (GHC.ST.$fFunctorST @ s))))
I don't understand what 'left-hand side', 'too complicated' and 'desugar' mean ;-)
It seems I have the same problem as described here: http://marc.info/?l=haskell-cafe&m=133242702914511
How do I diagnose this? How do I figure out what's causing the optimization to be disabled in my program?
Thanks!
回答1:
For what it's worth, on the 7.10 RC1 this error no longer occurs, so it looks like the fix to https://ghc.haskell.org/trac/ghc/ticket/8848 may have helped.
来源:https://stackoverflow.com/questions/18792388/haskell-ghc-specialize-causes-rule-left-hand-side-too-complicated-to