
On Wed, Apr 4, 2012 at 5:17 PM, Bardur Arantsson
Hi all,
I'm upgrading various bits and bobs to conduit 0.4.x, but I've hit a little snag with "sourceStateIO". The following function fails to compile:
sourceQuery :: Database -> String -> [SQLData] -> Source IO [SQLData] sourceQuery database sql parameters = sourceStateIO (do stmt <- SQL.prepare database sql return (Unbound,stmt)) (\(_,stmt) -> SQL.finalize stmt) (\(state,stmt) -> do -- Bind parameters if necessary. when (state == Unbound) $ do SQL.bind stmt parameters -- Fetch results. nextResult <- SQL.step stmt case nextResult of Done -> return StateClosed Row -> liftM (StateOpen (Bound,stmt)) $ SQL.columns stmt)
All the SQL.xyz bits run in the IO monad. This code runs fine in Conduit 0.2.x, but on Conduit 0.4.x it fails to compile with the following error:
src/Data/CQRS/EventStore/Backend/Sqlite3Utils.hs:43:3: No instance for (resourcet-0.3.2:Control.Monad.Trans.Resource.MonadResource IO) arising from a use of `sourceStateIO' Possible fix: add an instance declaration for (resourcet-0.3.2:Control.Monad.Trans.Resource.MonadResource IO) In the expression: sourceStateIO [rest elided; just the rest of the definition of sourceQuery] In an equation for `sourceQuery': sourceQuery database sql parameters = sourceStateIO [rest elided; just the rest of the definition of sourceQuery]
I can see that I'm missing an instance, but I can't seem to find a direct instance for MonadResource IO, nor can I tell which indirect instance could get me there. I there some specific import I need to get the necessary instances, or do I need to do something else?
Regards,
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
In conduit 0.2, a Source always implicitly wrapped up the inner monad in a ResourceT transformer. This caused complications, so now you need to explicitly add a ResourceT wrapper when it's needed. `sourceStateIO` is an example of such a function that requires the functionality of a `ResourceT`. Instead of making a requirements in the type that the inner monad be `ResourceT m`, there's a class constraint that the inner monad be an instance of `MonadResource`. tl;dr: Change your type signature to: sourceQuery :: Database -> String -> [SQLData] -> Source (ResourceT IO) [SQLData] You'll also need to call liftIO in a few places. HTH, Michael