
Martin Huschenbett
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?