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