[web-devel] A little trouble upgrading to conduit 0.4.x

Bardur Arantsson spam at scientician.net
Wed Apr 4 18:01:35 CEST 2012

On 04/04/2012 05:45 PM, Michael Snoyman wrote:
> On Apr 4, 2012 6:20 PM, "Bardur Arantsson"<spam at scientician.net>  wrote:
>> On 04/04/2012 04:22 PM, Michael Snoyman wrote:
>>> 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:
>>> 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`.
>> I'm wondering if I can just have a simple
>>     transPipe runResourceT $ sourceQuery ...
>> wrapper so that old callers can remain unmodified. This would give the
> old callers the (Source IO [SQLData]) that they expect. As far as I can
> tell, the open/close behavior would not be modified by transPipe.
>> Is there any reason that this wouldn't work?
>> Regards,
>> _______________________________________________
>> web-devel mailing list
>> web-devel at haskell.org
>> http://www.haskell.org/mailman/listinfo/web-devel
> Unfortunately that won't work, and would be very dangerous. In fact, I
> should update the docs to explain what transPipe does, and the limited
> cases in which it can work correctly.
> transPipe will call runResourceT on each individual monadic action
> performed by the Pipe in question. In this case, the result would be that
> runResourceT right after the first chunk of data is returned, which is
> certainly *not* what you want.

Ah, I see.

> The fact is that in version 0.2 of conduit, *every* Source, Sink, and
> Conduit lived in ResourceT. So if you want to keep things working the same
> way as before, just explicitly add the ResourceT wrappers. Your code
> already has a call to runResourceT somewhere to unwrap those.

Yup, indeed it does -- I just wanted to try to minimize disruption. I'll 
do as you suggest and just let the (ResourceT IO) propagate outwards in 
the type signatures until it hits a runResourceT :).

> Possibly a better approach would be to use type variables for the monads in
> your type signature and start off with a `Monad m` context. Then GHC will
> tell you when you need to use liftIO (because m isn't IO) and when you need
> to change the context to MonadResource.

Not sure what you mean here. Are you talking about starting with a 
maximally general type signature and then restricting based on the need 
for IO?

> I'll try to put together a larger example of this stuff in the next few
> days, but the combination of the upcoming Yesod release a Passover next
> week (and the requisite crunch at work) leaves me with less time than usual.

Some examples would indeed be nice, but there's no rush :).


More information about the web-devel mailing list