module Control.Monad.Ghc ( Ghc, runGhc,
GhcT, runGhcT,
GHC.GhcMonad(..),
module Control.Monad.Trans )
where
#if __GLASGOW_HASKELL__ < 706
import Prelude hiding ( catch )
#endif
import qualified Control.Exception.Extensible as E
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import qualified Control.Monad.Trans as MTL
import Control.Monad.Catch
import qualified GHC ( runGhc, runGhcT )
import qualified MonadUtils as GHC
import qualified Exception as GHC
#if __GLASGOW_HASKELL__ >= 702
import qualified GhcMonad as GHC
#else
import qualified HscTypes as GHC
#endif
#if __GLASGOW_HASKELL__ >= 706
import qualified DynFlags as GHC
#endif
newtype Ghc a = Ghc{ unGhc :: GHC.Ghc a }
deriving (Functor
,Monad
#if __GLASGOW_HASKELL__ < 702
,GHC.WarnLogMonad
#elif __GLASGOW_HASKELL__ >= 706
,GHC.HasDynFlags
#endif
,GHC.ExceptionMonad
#if __GLASGOW_HASKELL__ < 708
,GHC.MonadIO
#else
,MTL.MonadIO
,Applicative
#endif
,GHC.GhcMonad)
#if __GLASGOW_HASKELL__ < 708
instance Applicative Ghc where
pure = return
(<*>) = ap
instance MTL.MonadIO Ghc where
liftIO = GHC.liftIO
#endif
instance MonadThrow Ghc where
throwM = liftIO . E.throwIO
instance MonadCatch Ghc where
catch = GHC.gcatch
instance MonadMask Ghc where
#if __GLASGOW_HASKELL__ >= 700
mask f = wrap $ \s ->
mask $ \io_restore ->
unwrap (f $ \m -> (wrap $ \s' -> io_restore (unwrap m s'))) s
where
wrap = Ghc . GHC.Ghc
unwrap = GHC.unGhc . unGhc
#else
mask io = GHC.gblock $ io GHC.gunblock
#endif
uninterruptibleMask = mask
runGhc :: Maybe FilePath -> Ghc a -> IO a
runGhc f (Ghc m) = GHC.runGhc f m
newtype GhcT m a = GhcT { unGhcT :: GHC.GhcT (MTLAdapter m) a }
deriving (Functor
,Monad
#if __GLASGOW_HASKELL__ >= 706
,GHC.HasDynFlags
#endif
)
instance (Functor m, Monad m) => Applicative (GhcT m) where
pure = return
(<*>) = ap
runGhcT :: (Functor m, MonadIO m, MonadCatch m, MonadMask m) => Maybe FilePath -> GhcT m a -> m a
runGhcT f = unMTLA . GHC.runGhcT f . unGhcT
instance MTL.MonadTrans GhcT where
lift = GhcT . GHC.liftGhcT . MTLAdapter
instance MTL.MonadIO m => MTL.MonadIO (GhcT m) where
liftIO = GhcT . GHC.liftIO
#if __GLASGOW_HASKELL__ < 708
instance MTL.MonadIO m => GHC.MonadIO (GhcT m) where
liftIO = MTL.liftIO
#endif
instance MonadCatch m => MonadThrow (GhcT m) where
throwM = lift . throwM
instance (MonadIO m,MonadCatch m, MonadMask m) => MonadCatch (GhcT m) where
m `catch` f = GhcT ((unGhcT m) `GHC.gcatch` (unGhcT . f))
instance (MonadIO m, MonadMask m) => MonadMask (GhcT m) where
mask f = wrap $ \s ->
mask $ \io_restore ->
unwrap (f $ \m -> (wrap $ \s' -> io_restore (unwrap m s'))) s
where
wrap g = GhcT $ GHC.GhcT $ \s -> MTLAdapter (g s)
unwrap m = \s -> unMTLA ((GHC.unGhcT $ unGhcT $ m) s)
uninterruptibleMask = mask
instance (MonadIO m, MonadCatch m, MonadMask m) => GHC.ExceptionMonad (GhcT m) where
gcatch = catch
#if __GLASGOW_HASKELL__ >= 700
gmask f = mask (\x -> f x)
#else
gblock = mask_
#endif
#if __GLASGOW_HASKELL__ < 702
instance MTL.MonadIO m => GHC.WarnLogMonad (GhcT m) where
setWarnings = GhcT . GHC.setWarnings
getWarnings = GhcT GHC.getWarnings
#endif
instance (Functor m, MonadIO m, MonadCatch m, MonadMask m) => GHC.GhcMonad (GhcT m) where
getSession = GhcT GHC.getSession
setSession = GhcT . GHC.setSession
newtype MTLAdapter m a = MTLAdapter {unMTLA :: m a} deriving (Functor, Applicative, Monad)
instance MTL.MonadIO m => GHC.MonadIO (MTLAdapter m) where
liftIO = MTLAdapter . MTL.liftIO
instance (MonadIO m, MonadCatch m, MonadMask m) => GHC.ExceptionMonad (MTLAdapter m) where
m `gcatch` f = MTLAdapter $ (unMTLA m) `catch` (unMTLA . f)
#if __GLASGOW_HASKELL__ >= 700
gmask io = MTLAdapter $ mask (\f -> unMTLA $ io (MTLAdapter . f . unMTLA))
#else
gblock = MTLAdapter . mask_ . unMTLA
#endif