[Haskell-cafe] Re: Foralls in records

Adde adde at trialcode.com
Wed Mar 14 10:51:06 EDT 2007


Martin Huschenbett <huschi <at> gmx.org> writes:

> 
> Hi,
> 
> instead of writing a function getTransaction that retrieves the 
> connection you could write a function withConnection that doesn't return 
> the connection itself but performs an operation on the connection:
> 
> withConnection ::
> 	(forall c. Connection c => c -> Transaction a) -> Transaction a
> withConnection f = Transaction (\t <at> (TransactionT c) ->
> 	let Transaction tf = f c in tf t)
> 
> Then execute becomes:
> 
> execute :: String -> Transaction ()
> execute s = withConnection (\c -> connectionExecute c s)
> 
> Regards,
>    Martin.
> 
> > getConnection :: Transaction c
> > getConnection = Transaction (\t <at> (TransactionT c) -> (c, t))
> > 
> > class Connection c where
> >   connectionExecute :: c -> String -> Transaction ()
> > 
> > execute :: String -> Transaction ()
> > execute s = connectionExecute getConnection s
> 

Thanks, I would never have thought of that myself.
I replaced TransactionT with a typeclass called TransactionType to allow for 
different transaction structures for different databases.
The only thing i can't seem to figure out is how to bridge between the 
IO-monad and my own Transaction monad. 

class TransactionType t where
  transactionExecute :: t -> String -> IO ()

execute :: String -> Transaction ()
execute s = withTransaction (\t -> transactionExecute t s)

withTransaction :: (forall t. (TransactionType t) => t -> Transaction a) -> 
Transaction a
withTransaction f = Transaction (\t -> let Transaction tf = f t in tf t)

This is what I'm getting back:
Couldn't match expected type `Transaction ()' against inferred type `IO ()'

If i try to use liftIO i get this instead:
No instance for (MonadIO Transaction) arising from use of `liftIO'

I can't seem to find any examples of how to actually implement liftIO for a 
monad. Any ideas/pointers?




More information about the Haskell-Cafe mailing list