[Haskell-cafe] Re-exports of resourcet in conduit

Myles C. Maxfield myles.maxfield at gmail.com
Sun Jun 3 02:01:07 CEST 2012

It could be. Do you know how I can check which versions of packages other
packages have built against with Cabal? Will it help if I remove all the
relevant packages and then re-install only a single version?


On Saturday, June 2, 2012, Antoine Latter wrote:

> Is it possible that you are puuling in two different versions of the
> package that defines the MonadThrow class?
> That is, package a was built against version 1, but package b was built
> against version 2? This would make GHC think the type-class were
> incompatable.
> This is just a guess - I have not tried what you are trying.
> On Jun 2, 2012 6:35 PM, "Myles C. Maxfield" <myles.maxfield at gmail.com<javascript:_e({}, 'cvml', 'myles.maxfield at gmail.com');>>
> wrote:
>> To: Michael Snoyman
>> CC: haskell-cafe
>> Hello,
>> I'm having a problem working with the conduit library, and was hoping
>> you could help me out.
>> Data.Conduit re-exports ResourceT, MonadResource, and MonadThrow (but
>> not ExceptionT) from Control.Monad.Trans.Resource. I have a conduit
>> which operates on a monad in the MonadThrow class. I am trying to
>> figure out which MonadThrow class this should be (the
>> Data.Conduit.MonadThrow class, or the
>> Montrol.Monad.Trans.Resource.MonadThrow class, since apparently GHC
>> doesn't recognize them as the same, even though one is just a
>> re-export of the other).
>> If a user of this conduit wants to chain this conduit up with
>> something like sourceFile, the underlying monad has to be a member of
>> Data.Conduit.MonadResource and whatever MonadThrow class I chose to
>> use. I would like to be able to use an existing instance to lift the
>> class of the inner monad to the class of the entire monad stack (so I
>> don't have to tell the user of my conduit that they have to define
>> their own instances), and the only rule that I can find that does that
>> is the following from Data.Conduit:
>> Data.Conduit.MonadThrow m => Data.Conduit.MonadThrow
>> (Data.Conduit.ResourceT m)
>> However, GHC doesn't seem to think that
>> Control.Monad.Trans.Resource.ExceptionT is an instance of
>> Data.Conduit.MonadThrow:
>>    No instance for (Data.Conduit.MonadThrow (ExceptionT IO))
>>      arising from a use of `.....'
>> Control.Monad.Trans.Resource has a similar instance:
>> Control.Monad.Trans.Resource.MonadThrow m =>
>> Control.Monad.Trans.Resource.MonadThrow
>> (Control.Monad.Trans.Resource.ResourceT m)
>> but because sourceFile operates in the Data.Conduit.MonadResource
>> class, and Control.Monad.Trans.Resource.ResourceT isn't a member of
>> that class (it's only a member of
>> Control.Monad.Trans.Resource.MonadResource), that doesn't help:
>>    No instance for (Data.Conduit.MonadResource
>>                       (Control.Monad.Trans.Resource.ResourceT (ExceptionT
>> IO)))
>>      arising from a use of `.....'
>> It should be noted that neither module defines anything like the
>> following:
>> MonadResource m => MonadResource (ExceptionT m)
>> It seems like the underlying problem here is that:
>> 1) I am required to use the Control.Monad.Trans.Resource.ExceptionT
>> class, because Data.Conduit doesn't re-export it
>> 2) I am required to use the Data.Conduit.MonadResource class, because
>> sourceFile and others require it
>> 3) There doesn't seem to be an existing instance that bridges between the
>> two.
>> This seems like a fundamental flaw with re-exporting; it can only work
>> if you re-export every single last thing from the original module.
>> This doesn't seem tenable because the orignal module might not be
>> under your control, so its author can add new symbols whenever he/she
>> wants to.
>> I see two solutions to this problem:
>> 1) Re-export Control.Monad.Trans.Resource.ExceptionT in Data.Conduit.
>> This will work until someone adds something to the resourcet package
>> and someone wants to use the new addition and Data.Conduit.ResourceT
>> in the same stack
>> 2) Don't re-export anything in Data.Conduit; make sourceFile and
>> others explicitly depend on types in another module, but this might
>> break compatibility with existing programs if they use fully-qualified
>> symbol names.
>> 3) Make anyone who wants to use a monad stack in MonadThrow and
>> MonadResource define their own instances. This is probably no good
>> because it means that many different modules will implement the same
>> instance in potentially many different ways.
>> I feel like option 2) is probably the best solution here. I'm
>> perfectly happy to issue a pull request for whichever option you think
>> is best, but I don't know which solution you think is best for your
>> project. What do you think?
>> --Myles
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org <javascript:_e({}, 'cvml',
>> 'Haskell-Cafe at haskell.org');>
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120602/714304ee/attachment.htm>

More information about the Haskell-Cafe mailing list