
Hi. I'm experimenting with implementing database transactions as monads but I'm getting stuck on how to store a generic connection (only constrained by a typeclass) inside the transaction. The reason I'm doing it this way is that the connection could be a different kind of structure depending on what database the transaction is using. The goal is to enable all functions using the monad to extract the connection using getConnection. I realise I could probably get it running by adding a type parameter for the connection type to TransactionT and Transaction but I feel I shouldn't have to. All the compiler needs to know is that the contained value conforms to the interface of Connection. <code> data TransactionT = forall c. (Connection c) => TransactionT c data Transaction a = Transaction (TransactionT -> (a, TransactionT)) instance Monad Transaction where ... getConnection :: Transaction c getConnection = Transaction (\t@(TransactionT c) -> (c, t)) class Connection c where connectionExecute :: c -> String -> Transaction () execute :: String -> Transaction () execute s = connectionExecute getConnection s </code> I'm getting the following error: Couldn't match expected type `c' (a rigid variable) against inferred type `c1' (a rigid variable) `c' is bound by the type signature for `getConnection' at Database.hs:19:29 `c1' is bound by the pattern for `TransactionT' at Database.hs:20:33-46 In the expression: c In the expression: (c, t) In a lambda abstraction: \ (t@(TransactionT c)) -> (c, t)