My thought is that you could simply drop the IO from your type definition,

type PDState = StateT PD

You will need to change all of your type signature from "PDState <type>" to "PDState m <type>" to make them all polymorphic over the choice of monad. Then all you should need to do is to generalize the loop function to accept a line-fetching monad from the user:

loop :: m a -> PDState m a
loop getLine = forever $ do
  cmd <- lift getLine
  runCmd cmd

Note how liftIO was changed to lift, which works for any monad and comes built-in with the StateT monad.

Hope this helps!

Cheers,
Greg


On Oct 5, 2009, at 4:56 PM, Floptical Logic wrote:

The code below is a little interactive program that uses some state.
It uses StateT with IO to keep state.  My question is: what is the
best way to generalize this program to work with any IO-like
monad/medium?  For example, I would like the program to function as it
does now using stdin but I would also like it to function over IRC
using the Net monad from
<http://haskell.org/haskellwiki/Roll_your_own_IRC_bot>.  Thanks for
any suggestions.

-- begin code --
import Control.Monad
import Control.Monad.State
import Data.List

data PD = PD
   { pdCount :: Int
   , pdList  :: [String]
   } deriving (Show)

type PDState = StateT PD IO

main = runStateT loop (PD { pdCount = 0, pdList = [] })

loop :: PDState a
loop = forever $ do
   cmd <- liftIO getLine
   runCmd cmd

runCmd :: String -> PDState ()
runCmd "Inc" = increment
runCmd "PrintCount" = liftIO . print =<< getCount
runCmd "PrintList" = liftIO . print =<< getList
runCmd str | "Add " `isPrefixOf` str = addToList $ drop 4 str
runCmd _ = return ()

getCount :: PDState Int
getCount = pdCount `liftM` get

getList :: PDState [String]
getList = pdList `liftM` get

increment :: PDState ()
increment = modify $ \st -> st { pdCount = pdCount st + 1 }

addToList :: String -> PDState ()
addToList str = modify $ \st -> st { pdList = pdList st ++ [str]}
-- end code --
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to