+newtype Generate e a = Generate {
+ runGenerate :: EMT e (State GState) a }
+ deriving (Monad, MonadState GState)
+
+instance MonadState st (EMT e (StateT st IO)) where
+ get = lift St.get
+ put x = lift (St.put x)
+
+instance MonadState st (EMT e (State st)) where
+ get = lift St.get
+ put x = lift (St.put x)
+
+-- | IO version of Generate monad
+newtype GenerateIO e a = GenerateIO {
+ runGenerateIO :: EMT e (StateT GState IO) a }
+ deriving (Monad, MonadState GState, MonadIO)
+
+instance MonadIO (EMT e (StateT GState IO)) where
+ liftIO action = lift $ liftIO action
+
+instance Generator e GenerateIO where
+ throwG e = GenerateIO (throw e)
+
+instance (MonadState GState (EMT e (State GState))) => Generator e Generate where
+ throwG e = Generate (throw e)
+
+execGenerateIO cp (GenerateIO emt) = do
+ let caught = emt `catch` (\(e :: SomeException) -> fail $ show e)
+ execStateT (runEMT caught) (emptyGState {classPath = cp})
+
+execGenerate cp (Generate emt) = do
+ let caught = emt `catch` (\(e :: SomeException) -> fail $ show e)
+ execState (runEMT caught) (emptyGState {classPath = cp})
+
+-- | Update ClassPath
+withClassPath :: ClassPath () -> GenerateIO e ()
+withClassPath cp = do
+ res <- liftIO $ execClassPath cp
+ st <- St.get
+ St.put $ st {classPath = res}