MonadIO #9

Open
drdo opened this Issue Jan 14, 2012 · 13 comments

Projects

None yet

5 participants

@drdo
drdo commented Jan 14, 2012

Would it be possible to change fold and friends to accept a MonadIO instead of specifically IO?

Thank you

@lpsmith
Owner
lpsmith commented Jan 15, 2012

Yes, I do very much plan on doing this. My hangup at the moment is that generalizing withTransaction requires committing to a solution to deal with exceptions, and I'm really none too enthusiastic about either MonadCatchIO or monad-control. I suppose I could generalize functions that don't require dealing with exceptions inside the generalized monad, however.

Also, beware that I have not tested fold extensively. And in particular there are some caveats with using fold when the database returns columns whose type is not included in BuiltinTypes, as noted in commit bce0d38.

@drdo
drdo commented Jan 15, 2012

You could also use Data.Conduit

@lpsmith
Owner
lpsmith commented Jan 15, 2012

Data.Conduit uses monad-control. And I see your point with regard to fold; it's far less useful in it's ungeneralized state, potentially requiring some rather unnatural and ugly circumlocutions.

One of the problems with the current implementation of fold is that the database connection is left in the wrong state if the function it is passed throws an exception. So I do need the ability to deal with exceptions.

And, honestly, I could probably close my eyes and temporarily forget about the things that MonadCatchIO and monad-control get wrong, but I don't like the fact that I'd basically have to pick between the Yesod and Snap worlds, delegating one of them to a second-class citizen.

Although, it is somewhat unfortunate that packages that provide a monad (such as Yesod and Snap) don't supply instances for both alternatives. But you actually have to pick one when you provide a function that must deal with exceptions thrown by functional arguments, such as withTransaction and fold.

@lpsmith
Owner
lpsmith commented Jan 15, 2012

If you are willing to say, what does your monad stack look like out of curiousity?

@drdo
drdo commented Jan 15, 2012

I've been trying to find a set of suitable libraries that can play nice together for a pretty simple web backend and have been largely disappointed. I'm at that point where i'll just do whatever and move on. Right now i was using CGIT IO.

@lpsmith
Owner
lpsmith commented Jan 15, 2012

Oh fun, now we are talking three ways of catching exceptions, MonadCatchIO-mtl, MonadCatchIO-transformers, and monad-control. I'd forgotten that MonadCatchIO-mtl and MonadCatchIO-transformers are completely separate, incompatible packages. (though of a similar flavor, whereas monad-control is different)

And none of which get things correct. Though I don't really know what the correct thing is, exactly.

This issue has been frustrating me; it's something the Haskell community really needs to get serious about fixing.

@lpsmith
Owner
lpsmith commented Jan 15, 2012

How important is streaming to your intended application? You could generalize query and execute yourself, which need not be concerned with controlling exceptions. Also, you could open a cursor for your query and implement streaming through query and execute alone...

@drdo
drdo commented Jan 15, 2012

The temporary solution i ended up going with is just wrapping up connect, query, execute and the transaction stuff in a ResourceT and providing queryList and querySource. The Source in querySource will obviously load everything into memory instead of actually streaming, but i plan to fix that in the future when i have time.

@lpsmith
Owner
lpsmith commented Jan 15, 2012

Well, using a database cursor is not particularly difficult. See close, declare, fetch, and move for details.

@k0001
k0001 commented Nov 29, 2013

In the project I'm currently working on I've been rewriting the with* functions so that they work on any (MonadIO m, MonadCatch m). MonadCatch is from the exceptions package by Edward Kmett.

I don't yet know what are the pros and cons of MonadCatch over any of the alternatives, but I know that is very straightforward to use and that it plays well with pipes-safe which is another library I'm using in my project. Unless I discover some shortcomings or some of you tell me that MonadCatch is not a good approach, I'll continue to research its limitations and hopefully prepare a pull request embracing MonadIO and MonadCatch throughout the library.

So, I thought I'd mention that in case someone wants to yell at me :)

@lpsmith
Owner
lpsmith commented Nov 30, 2013

Yeah, the exceptions package is very much in the spirit of MonadCatchIO, though with the updated mask functions and with some of the problematic instances removed. Honestly, I think I like that better than the apparently ascendant monad-control, which I'm not particularly fond of.

My one possible misgiving about exceptions is that bracket isn't in the typeclass, or possibly a separate typeclass. I've heard rumors that people suspect there are monads that can implement bracket but not catch. But this is not something I understand well enough to make a substantive comments about.

My inclination at this point is to adopt monad-control when (if?) Snap migrates to it.

@ibotty
ibotty commented Oct 8, 2014

fyi: snap 1.0 will use monad-control (see its HEAD cabal file.)

@tstat tstat referenced this issue in tomjaguarpaw/haskell-opaleye Nov 10, 2015
Merged

Add runQueryFold for streaming database queries #69

@bgamari
Contributor
bgamari commented Apr 23, 2016

What is the current status of this? It is quite unfortunate that postgresql-simple doesn't have a decent streaming story.

@bgamari bgamari added a commit to bgamari/postgresql-simple that referenced this issue Sep 30, 2016
@bgamari bgamari Generalize the base monad of fold-like operations
Previously the fold-like operations were restricted to fold operations
in `IO`, greatly limiting their usefulness. Here we generalize them to
any `MonadMask`, provided by the widely-used `exceptions` library.

Resolves #9.
5a418fc
@bgamari bgamari added a commit to bgamari/postgresql-simple that referenced this issue Sep 30, 2016
@bgamari bgamari Generalize the base monad of fold-like operations
Previously the fold-like operations were restricted to fold operations
in `IO`, greatly limiting their usefulness. Here we generalize them to
any `MonadMask`, provided by the widely-used `exceptions` library.

Resolves #9.
39e9789
@bgamari bgamari added a commit to bgamari/postgresql-simple that referenced this issue Oct 1, 2016
@bgamari bgamari Generalize the base monad of fold-like operations
Previously the fold-like operations were restricted to fold operations
in `IO`, greatly limiting their usefulness. Here we generalize them to
any `MonadMask`, provided by the widely-used `exceptions` library.

Resolves #9.
ec37888
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment