postgresql-simple icon indicating copy to clipboard operation
postgresql-simple copied to clipboard

MonadIO

Open drdo opened this issue 13 years ago • 16 comments

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

Thank you

drdo avatar Jan 14 '12 18:01 drdo

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 bce0d389fd16a35a88841bb8434fab264b824993.

lpsmith avatar Jan 15 '12 01:01 lpsmith

You could also use Data.Conduit

drdo avatar Jan 15 '12 03:01 drdo

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 avatar Jan 15 '12 04:01 lpsmith

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

lpsmith avatar Jan 15 '12 04:01 lpsmith

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.

drdo avatar Jan 15 '12 05:01 drdo

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 avatar Jan 15 '12 06:01 lpsmith

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...

lpsmith avatar Jan 15 '12 06:01 lpsmith

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.

drdo avatar Jan 15 '12 10:01 drdo

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

lpsmith avatar Jan 15 '12 15:01 lpsmith

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 :)

k0001 avatar Nov 29 '13 23:11 k0001

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.

lpsmith avatar Nov 30 '13 20:11 lpsmith

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

ibotty avatar Oct 08 '14 09:10 ibotty

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

bgamari avatar Apr 23 '16 00:04 bgamari

Is a withTransaction :: (MonadIO m) => Connection -> m a -> m a part of this issue itself? Any update on this?

saurabhnanda avatar Jun 17 '17 19:06 saurabhnanda

Hi. Is withTransaction going to accept a generalized Monad soon?

centromere avatar Jul 11 '17 20:07 centromere

:+1:

Because right now we can’t throw Servant errors in withTransaction, can we?

michalrus avatar Sep 13 '17 23:09 michalrus