[Haskell] State, StateT and lifting

Juan Carlos Arevalo Baeza jcab.lists at JCABs-Rumblings.com
Fri Mar 18 17:00:37 EST 2005

   I've recently been experimenting with a little "make" engine I've 
implemented in Haskell. I'm using state monads to do the work. I was 
attempting to use two functions:

matchRuleST :: String -> State RuleSet (Maybe Rule)
makeST :: String -> StateT RuleSet IO ()

   matchRuleST doesn't really need IO for anything (it just works on the 
current state "RuleSet"). makeST needs IO (it does file date 
comparisons, actions on the files, etc... the usual "make" stuff). The 
problem is how to properly use matchRuleST from makeST. I searched for a 
proper lifting function (similar to liftIO, but which would lift from 
the state monad), and couldn't find one. So I changed the function 
signature to:

matchRuleST :: String -> StateT RuleSet IO (Maybe Rule)

   and everything worked just fine.

   Then, I decided to try again, and came up with this function:

liftState :: State s a -> StateT s m a
liftState s = do
    state1 <- get
        let (result, state) = evalState (do {result <- s; state <- get; 
return (result, state)}) state1 in do
            put state
            return result

   which works like a charm and is not even IO-dependent.

   I'm learning here, so the questions are: Is there a better way to do 
this? Did I miss a similar function anywhere? Did I miss some useful 
abstraction that makes this a moot point?

   I'm using GHC 6.4.


More information about the Haskell mailing list