Giter Site home page Giter Site logo

Comments (14)

snoyberg avatar snoyberg commented on August 20, 2024

Let's including the emails discussion. My first response:

Hmm... not only does it not exist, but I don't see an immediately obvious way of implementing it even with access to the internals, given the current implementation. You can use transResourceT to change the inner monad, however.

In order to achieve this behavior, I think we'd need to add the following method to the MonadResource typeclass:

liftResourceT :: ResourceT IO a -> m a

For the ResourceT instance, we'd have:

liftResourceT = transResourceT liftIO

and for everything else:

liftResourceT = lift . liftResourceT

In fact, with that approach, we could probably take the other three methods out of the typeclass. This would technically be a breaking change, so we'd need to bump to 0.4.

If we're thinking about this, here's another change I was thinking of: making MonadBaseControl IO m a superclass of MonadResource. It would prevent some transformers (particularly ContT) from being instances of MonadResource, but would simplify some type signatures (e.g., the http function in http-conduit). I'm leaning more heavily away from this change as I think about it more, but I thought I'd mention it.

from conduit.

aristidb avatar aristidb commented on August 20, 2024

And the relevant part of my response to your first response:

Sounds good. Perhaps there is a way to have the liftResourceT not have to change the below-ResourceT monad, so the ResourceT the instance could be liftResourceT = id, and add another function that takes care of the transResourceT, just to split up responsibilities and perhaps be a bit more flexible.

Not sure if that's worth the added complexity.

from conduit.

snoyberg avatar snoyberg commented on August 20, 2024

I think we'd have to play around with the types quite a bit to make that change (what would the signature of such a decomposed function look like?). Did you have an idea on what that would look like?

from conduit.

aristidb avatar aristidb commented on August 20, 2024

Again, not sure if it's worth the added complexity, but one way might be roughly like this (pseudo-Haskell):

class MonadResource ... r where
    type BelowResourceT r :: * -> *
    liftResourceT :: ResourceT (BelowResourceT r) a -> r a

instance MonadResource (ResourceT m) where
    type BelowResourceT (ResourceT m) = m
    liftResourceT = id

instance MonadResource m => MonadResource (FooT m a) where
    type BelowResourceT (FooT m) = BelowResourceT m
    liftResourceT = lift

Basically a lift that stops at ResourceT.

from conduit.

snoyberg avatar snoyberg commented on August 20, 2024

Got it, that makes sense. I don't think the extra complexity is warranted, however. I've made a new branch for the modified version, check out the attached commit.

from conduit.

aristidb avatar aristidb commented on August 20, 2024

I like it.

One thing popped in my mind: Would it be possible to make MonadResource compatible with ST or ExceptionT ST? I guess ST itself has no exceptions, but with ExceptionT you get them and then you probably might want resource management too. Not that I need it myself, ResourceT IO makes me happy, but I guess as a Haskeller one just sometimes feels this urge for generality. :)

from conduit.

snoyberg avatar snoyberg commented on August 20, 2024

The original implementation of resourcet that went into conduit 0.0 allowed for such generality... and it was a mess. More to the point: the only monad in which you should be allowed to allocate resources is IO (and transformers built on it). So there shouldn't be any use case which would require resourcet.

from conduit.

aristidb avatar aristidb commented on August 20, 2024

Fair enough. Is there any reason for ResourceT to be a transformer, then? Because you might as well just use ResourceT IO all the time and build your transformer stacks on top of that. The new MonadResource class already strongly encourages that, I think. :)

from conduit.

snoyberg avatar snoyberg commented on August 20, 2024

There are many cases where you need a separate inner monad. Imagine the following contrived example:

import Control.Monad.Writer
import Data.Conduit
import qualified Data.Conduit.List as CL
import Data.Conduit.Binary (sourceFile)

foo fp = runWriterT $ runResourceT $ sourceFile fp $$ CL.mapM_ tell

More realistic use cases come into play fast when dealing with libraries that define their own monad stacks, and you want to be able to run some conduit code that interacts with them.

from conduit.

aristidb avatar aristidb commented on August 20, 2024

Those are not instances of MonadResource then though?
Am 14.08.2012 16:08 schrieb "Michael Snoyman" [email protected]:

There are many cases where you need a separate inner monad. Imagine the
following contrived example:

import Control.Monad.Writer
import Data.Conduit
import qualified Data.Conduit.List as CL
import Data.Conduit.Binary (sourceFile)

foo fp = runWriterT $ runResourceT $ sourceFile fp $$ CL.mapM_ tell

More realistic use cases come into play fast when dealing with libraries
that define their own monad stacks, and you want to be able to run some
conduit code that interacts with them.


Reply to this email directly or view it on GitHubhttps://github.com//issues/61#issuecomment-7726840.

from conduit.

aristidb avatar aristidb commented on August 20, 2024

Nevermind, I misunderstood it for a bit. OK, I think the implementation in that branch is good.

from conduit.

nh2 avatar nh2 commented on August 20, 2024

@snoyberg +1 for your last argument, it can cause bad headaches when transformers want to sit in a certain place. I recently had that problem with Haskeline, and it made it impossible to implement a simple use case (you couldn't use local to change environments any more).

from conduit.

aristidb avatar aristidb commented on August 20, 2024

@nh2 I just misunderstood the way MonadResource works, I don't actually disagree anymore. The implementation in 6953fc2 looks good to me.

from conduit.

snoyberg avatar snoyberg commented on August 20, 2024

The new version is up on Hackage now (was released a while ago actually).

from conduit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.