[web-devel] A little trouble upgrading to conduit 0.4.x
Michael Snoyman
michael at snoyman.com
Wed Apr 4 16:22:48 CEST 2012
On Wed, Apr 4, 2012 at 5:17 PM, Bardur Arantsson <spam at scientician.net> wrote:
> 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 at 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
More information about the web-devel
mailing list