bracket, (un)block and MonadIO

Lunar lunar@lautre.net
Tue, 2 Sep 2003 14:38:59 +0100


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I'm trying to make generic helper functions for database querying.  I would
like to be able to define functions that work for every monad that holds a
database connection and is built on top of the IO monad.  For this, I have
defined the following type class:

> class MonadIO m => ConnectedM m where
>     getConnection :: m Connection

The 'query' function from the database library I am using returns a Statement
which has to be closed under all circumstances (especially when an exception
is thrown); I am using bracket to ensure this, in the following helper
function:

> withQuery :: ConnectedM m => (Statement -> m a) -> String -> m a
> withQuery f q =
>     do conn <- getConnection
>        bracket
>            (liftIO $ query conn q)
>            (\ s -> liftIO $ closeStatement s)
>            f

However, the definition of bracket relies on block and unblock, which have the
following types:
> bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
> block :: IO a -> IO a
> unblock :: IO a -> IO a

This forces f to be an IO action in the above withQuery function.  If bracket,
block, and unblock had these types, my helper function would be well typed:

> bracket :: MonadIO m => m a -> (a -> m b) -> (a -> m c) -> m c
> block :: MonadIO m => m a -> m a
> unblock :: MonadIO m => m a -> m a

Would anything prevent block, unblock, bracket (and other similar functions
working on IO actions) from being generalized to all intances of MonadIO?

Lunar.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE/VJ11d1rcjNWgdWQRAqeGAJ9tUgXPkOwAfyWj6wTHEGNQ9UYnGgCfSn9S
Tf9lH2Tq5pMZVhTM/WVO1/o=
=fPqV
-----END PGP SIGNATURE-----