diff --git a/ghc-session.cabal b/ghc-session.cabal
--- a/ghc-session.cabal
+++ b/ghc-session.cabal
@@ -1,5 +1,5 @@
 name:                ghc-session
-version:             0.1.1.0
+version:             0.1.2.0
 synopsis:            Simplified GHC API
 description:         Simplified GHC API
 license:             MIT
@@ -24,7 +24,8 @@
         Language.Haskell.Session.Hint.Util
         Language.Haskell.Session.Binding
         Language.Haskell.Session.Session
-    -- other-modules:
+    other-modules:
+        Language.Haskell.Session.Instances
     -- other-extensions:
     default-language:    Haskell2010
     build-depends:      base >=4.7 && <4.9,
@@ -32,7 +33,8 @@
                         ghc,
                         ghc-mtl,
                         ghc-paths,
-                        transformers
+                        transformers,
+                        transformers-compat
 
     hs-source-dirs:     src
     default-language:   Haskell2010
diff --git a/src/Language/Haskell/Session.hs b/src/Language/Haskell/Session.hs
--- a/src/Language/Haskell/Session.hs
+++ b/src/Language/Haskell/Session.hs
@@ -1,9 +1,11 @@
 module Language.Haskell.Session (
     module Language.Haskell.Session.Session,
     module Language.Haskell.Session.Binding,
+    module Language.Haskell.Session.Instances,
     module Language.Haskell.Session.Hint.Typecheck,
 ) where
 
 import Language.Haskell.Session.Binding
 import Language.Haskell.Session.Hint.Typecheck
+import Language.Haskell.Session.Instances
 import Language.Haskell.Session.Session
diff --git a/src/Language/Haskell/Session/Instances.hs b/src/Language/Haskell/Session/Instances.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Session/Instances.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE StandaloneDeriving #-}
+
+module Language.Haskell.Session.Instances (
+    module Control.Monad.Ghc,
+    module Exception,
+    module DynFlags
+) where
+
+import Control.Monad.Ghc
+import Control.Monad.IO.Class     (MonadIO)
+import Control.Monad.Trans.Except
+import DynFlags (HasDynFlags (getDynFlags))
+import Exception (ExceptionMonad (gcatch, gmask))
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.State
+import Control.Monad.Trans.State.Lazy as StateL
+import qualified Control.Monad.Catch as Catch
+import  Control.Monad.Catch
+
+
+
+instance (GhcMonad m,  MonadIO m) => GhcMonad (IdentityT m) where
+    getSession = lift $ getSession
+    setSession = lift . setSession
+
+instance (GhcMonad m,  MonadIO m) => GhcMonad (ExceptT e m) where
+    getSession = lift $ getSession
+    setSession = lift . setSession
+
+instance (GhcMonad m,  MonadIO m) => GhcMonad (StateT s m) where
+    getSession = lift $ getSession
+    setSession = lift . setSession
+
+instance (MonadIO m, ExceptionMonad m)  => ExceptionMonad (ExceptT e m) where
+    gcatch (ExceptT m) f = ExceptT $ gcatch m (runExceptT . f)
+    gmask f = ExceptT $ gmask f' where
+        f' g = runExceptT $ f g' where
+            g' (ExceptT m)= ExceptT $ g m
+
+instance (MonadIO m, ExceptionMonad m)  => ExceptionMonad (IdentityT m) where
+    gcatch (IdentityT m) f = IdentityT $ gcatch m (runIdentityT . f)
+    gmask f = IdentityT $ gmask f' where
+        f' g = runIdentityT $ f g' where
+            g' (IdentityT m)= IdentityT $ g m
+
+instance (MonadIO m, ExceptionMonad m)  => ExceptionMonad (StateT s m) where
+    gcatch m h = StateT $ \ s -> runStateT m s `gcatch` \ e -> runStateT (h e) s
+    gmask a = StateT $ \s -> gmask $ \u -> runStateT (a $ q u) s
+        where q :: (m (a, s) -> m (a, s)) -> StateT s m a -> StateT s m a
+              q u (StateT b) = StateT (u . b)
+
+instance (MonadIO m, HasDynFlags m) => HasDynFlags (IdentityT m) where
+    getDynFlags = lift $ getDynFlags
+
+instance (MonadIO m, HasDynFlags m) => HasDynFlags (ExceptT e m) where
+    getDynFlags = lift $ getDynFlags
+
+instance (MonadIO m, HasDynFlags m) => HasDynFlags (StateT s m) where
+    getDynFlags = lift $ getDynFlags
diff --git a/src/Language/Haskell/Session/Session.hs b/src/Language/Haskell/Session/Session.hs
--- a/src/Language/Haskell/Session/Session.hs
+++ b/src/Language/Haskell/Session/Session.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE ConstraintKinds #-}
+
 module Language.Haskell.Session.Session (
     -- * Session
-    Session,
+    SessionMonad,
     run,
     runWith,
 
@@ -39,16 +41,17 @@
 import           Control.Monad.IO.Class (liftIO)
 import           Data.Typeable          (Typeable)
 import qualified DynFlags
+import           GHC                    (GhcMonad)
 import qualified GHC
+import qualified GHC.Paths              as Paths
 import qualified HscTypes
-import qualified GHC.Paths  as Paths
 
 import           Language.Haskell.Config            as Config
 import qualified Language.Haskell.Session.Binding   as Binding
 import qualified Language.Haskell.Session.Hint.Eval as HEval
 
 
-type Session = MGHC.Ghc
+type SessionMonad m = (GhcMonad m, Catch.MonadMask m, Catch.MonadCatch m)
 
 type Import = String
 
@@ -57,18 +60,18 @@
 --------------------------------------------------------------------------------
 
 -- | Run session with default config.
-run :: Session a -> IO a
-run session = MGHC.runGhc (Just Paths.libdir) $ initialize >> session
+run :: (MGHC.MonadIO m, Catch.MonadMask m, Functor m) => MGHC.GhcT m a -> m a
+run session = MGHC.runGhcT (Just Paths.libdir) $ initialize >> session
 
 
 -- | Run session with custom GHC config.
-runWith :: Config -> Session a -> IO a
+runWith :: Config -> MGHC.Ghc a -> IO a
 runWith config session = MGHC.runGhc (Just $ Config.topDir config)
                        $ initializeWith config >> session
 
 
 -- | Initialize session with custom GHC config.
-initializeWith :: Config -> Session ()
+initializeWith :: GhcMonad m => Config -> m ()
 initializeWith config = do
     initialize
     let globalPkgDb = Config.global $ Config.pkgDb config
@@ -85,7 +88,7 @@
                 }
 
 -- | Initialize session with default config.
-initialize :: Session ()
+initialize :: GhcMonad m => m ()
 initialize = do
     setStrFlags ["-fno-ghci-sandbox"]
     flags <- GHC.getSessionDynFlags
@@ -101,7 +104,7 @@
 --------------------------------------------------------------------------------
 
 -- | Set ghc command line arguments.
-setStrFlags :: [String] -> Session ()
+setStrFlags :: GhcMonad m => [String] -> m ()
 setStrFlags strFlags = do
     flags <- GHC.getInteractiveDynFlags
     (flags2, leftovers, warns) <- GHC.parseDynamicFlags flags $ map GHC.noLoc strFlags
@@ -116,12 +119,12 @@
 --------------------------------------------------------------------------------
 
 -- | Set imports and replace existing ones.
-setImports :: [Import] -> Session ()
+setImports :: GhcMonad m => [Import] -> m ()
 setImports = GHC.setContext . map (GHC.IIDecl . GHC.simpleImportDecl . GHC.mkModuleName)
 
 
 -- | Run a code with temporary imports.
-withImports :: [Import] -> Session a -> Session a
+withImports :: (Catch.MonadMask m, GhcMonad m) => [Import] -> m a -> m a
 withImports imports action = sandboxContext $ do
     setImports imports
     action
@@ -135,19 +138,19 @@
 --------------------------------------------------------------------------------
 
 -- | Set GHC extension flags.
-setFlags :: [DynFlags.ExtensionFlag] -> Session ()
+setFlags :: GhcMonad m => [DynFlags.ExtensionFlag] -> m ()
 setFlags flags = do
     current <- GHC.getSessionDynFlags
     void $ GHC.setSessionDynFlags $ foldl DynFlags.xopt_set current flags
 
 -- | Unset GHC extension flags.
-unsetFlags :: [DynFlags.ExtensionFlag] -> Session ()
+unsetFlags :: GhcMonad m => [DynFlags.ExtensionFlag] -> m ()
 unsetFlags flags = do
     current <- GHC.getSessionDynFlags
     void $ GHC.setSessionDynFlags $ foldl DynFlags.xopt_unset current flags
 
 -- | Run a code with temporary GHC extension flags.
-withExtensionFlags :: [DynFlags.ExtensionFlag] -> [DynFlags.ExtensionFlag] -> Session a -> Session a
+withExtensionFlags :: (Catch.MonadMask m, GhcMonad m) => [DynFlags.ExtensionFlag] -> [DynFlags.ExtensionFlag] -> m a -> m a
 withExtensionFlags enable disable action = sandboxDynFlags $ do
     setFlags enable
     unsetFlags disable
@@ -158,7 +161,7 @@
 --------------------------------------------------------------------------------
 
 -- | Run statement as in ghci.
-runStmt :: String -> Session ()
+runStmt :: (Catch.MonadCatch m, GhcMonad m) => String -> m ()
 runStmt stmt = do
     result <- interceptErrors $ GHC.runStmtWithLocation location 1 stmt GHC.RunToCompletion
     case result of
@@ -167,27 +170,27 @@
         GHC.RunBreak {}     -> fail $ "runStmt : RunBreak"
 
 -- | Run declaration as in Haskell source file.
-runDecls :: String -> Session ()
+runDecls :: (Catch.MonadCatch m, GhcMonad m) => String -> m ()
 runDecls decls = do
     void $ interceptErrors $ GHC.runDeclsWithLocation location 1 decls
 
 
 -- | Bind expression do a variable using `let` syntax.
-runAssignment :: String -> String -> Session ()
+runAssignment :: (Catch.MonadCatch m, GhcMonad m) => String -> String -> m ()
 runAssignment asigned asignee = do
     Binding.removeBinding asigned
     -- do not use runDecls here: its bindings are hard to remove and cause memory leaks!
     runStmt $ "let " ++ asigned ++ " = " ++ asignee
 
 -- | Bind expression to a variable using `bind` syntax. Expression must have type `IO a`.
-runAssignment' :: String -> String -> Session ()
+runAssignment' :: (Catch.MonadCatch m, GhcMonad m) => String -> String -> m ()
 runAssignment' asigned asignee = do
     Binding.removeBinding asigned
     runStmt $ asigned ++ " <- " ++ asignee
 
 
 -- | Evaluate expression.
-interpret :: Typeable a => String -> Session a
+interpret :: (Catch.MonadCatch m, GhcMonad m) => Typeable a => String -> m a
 interpret = interceptErrors . HEval.interpret
 
 --------------------------------------------------------------------------------
@@ -195,20 +198,20 @@
 --------------------------------------------------------------------------------
 
 -- | Run a code which can safely modify DynFlags - it will be restored on exit.
-sandboxDynFlags :: Session a -> Session a
+sandboxDynFlags :: (Catch.MonadMask m, GhcMonad m) => m a -> m a
 sandboxDynFlags = bracket GHC.getSessionDynFlags GHC.setSessionDynFlags . const
 
 
 -- | Run a code which can safely modify Context w- it  will be restored on exit.
-sandboxContext :: Session a -> Session a
+sandboxContext :: (Catch.MonadMask m, GhcMonad m) => m a -> m a
 sandboxContext = bracket GHC.getContext GHC.setContext . const
 
 
 -- | Restore session when exception will be raised.
-interceptErrors :: MGHC.Ghc a -> Session a
+interceptErrors :: (Catch.MonadCatch m, GhcMonad m) => m a -> m a
 interceptErrors ghc = do
     sessionBackup <- GHC.getSession
-    let handler :: Catch.SomeException -> MGHC.Ghc a
+    let handler ::(Catch.MonadCatch m, GhcMonad m) => Catch.SomeException -> m a
         handler otherErr = do
             GHC.setSession sessionBackup
             Exception.throw otherErr
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,10 +1,10 @@
 module Main where
 
+import           Control.Monad.IO.Class   (liftIO)
 import qualified Language.Haskell.Session as Session
-import Control.Monad.IO.Class (liftIO)
 
 
-
+main :: IO ()
 main = Session.run $ do
     Session.setImports ["Prelude"]
     Session.runAssignment "x" "5"
