[Haskell-cafe] Re-exports of resourcet in conduit
michael at snoyman.com
Sun Jun 3 11:00:50 CEST 2012
The easiest thing to do is just build your code with cabal, which will
ensure you're using consistent versions. (Similar questions came up
twice recently on Stack Overflow.) Wiping our your ~/.ghc and
installing from scratch should work also, but it's like using a
tactical nuke instead of a scalpel.
As for checking versions of dependencies, try `ghc-pkg describe conduit`.
On Sun, Jun 3, 2012 at 3:01 AM, Myles C. Maxfield
<myles.maxfield at gmail.com> wrote:
> 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
>> 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>
>>> To: Michael Snoyman
>>> CC: haskell-cafe
>>> 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
>>> 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.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
>>> arising from a use of `.....'
>>> It should be noted that neither module defines anything like the
>>> 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
>>> 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?
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
More information about the Haskell-Cafe