[Haskell-cafe] Re: Foralls in records
adde at trialcode.com
Wed Mar 14 10:51:06 EDT 2007
Martin Huschenbett <huschi <at> gmx.org> writes:
> 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)
> > 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) ->
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