[Haskell-cafe] Generalizing IO

David Menendez dave at zednenem.com
Tue Oct 6 00:12:23 EDT 2009

On Mon, Oct 5, 2009 at 11:54 PM, Floptical Logic
<flopticalogic at gmail.com> wrote:
>> Instead of specifying the monad implementation, specify the interface.
>> That is, you are using state operations (from MonadState) and IO
>> operations (from MonadIO). Try removing all the type signatures that
>> mention PDState and see what you get.
>> E.g., loop :: (MonadState PD m, MonadIO m) => m a
> If I were to make an instance of MonadIO be a parameter to StateT and
> I wanted to use the Net monad (from Roll your own IRC bot on the wiki)
> with it, I would need to make Net an instance of MonadIO.  What would
> this instance look like?

You're referring to this type?

type Net = ReaderT Bot IO

That already is an instance of MonadIO. The relevant instances are

instance MonadIO IO where
    liftIO = id

instance MonadIO m => MonadIO (ReaderT r m) where
    liftIO = lift . liftIO

> I think the loop function is the least of my worries.  I am more
> concerned about the runCmd function.  What would go in place of print
> in runCmd?

You're already using liftIO from MonadIO in the definition of runCmd,
so no changes need to be made.

Now, I didn't notice that getCount, getList, and increment don't take
arguments, so you either need to provide explicit type signatures or
set NoMonomorphismRestriction. If you do the latter and load the code
into ghci, you get:

*Main> :t runCmd
runCmd :: (MonadState PD m, MonadIO m) => [Char] -> m ()

Dave Menendez <dave at zednenem.com>

More information about the Haskell-Cafe mailing list