Gabriella439 / pipes-concurrency

Concurrency for the pipes ecosystem
BSD 3-Clause "New" or "Revised" License
43 stars 12 forks source link

Using `exceptions` so that we can avoid cornering `withSpawn` to `IO`? #35

Open k0001 opened 9 years ago

k0001 commented 9 years ago

Using the exceptions package we could change the signature of withSpawn from:

withSpawn 
    :: Buffer a 
    -> ((Output a, Input a) -> IO b) 
    -> IO b

To the more general:

withSpawn
    :: (Monad IO, MonadMask m) 
    => Buffer a 
    -> ((Output a, Input a) -> m b) 
    -> m b

This means that withSpawn could be used “higher on the monad tower” than IO, which is a good thing from an usability point of view, as the user won't need to worry that much about how to mix and match IO and other monads. I've already had to do this change myself on a piece of code that I'm writting, but it would be nice if this was the behaviour out of the box.

About the choice of exceptions: During last year this package has established itself as a preferred choice in the community (compared to monad-control and others), and pipes-safe already uses it, so it makes sense to embrace it here too. According to http://packdeps.haskellers.com/reverse/exceptions 116 packages depend on exceptions today.

If you think this is a good idea, I can submit a pull-request with the necessary changes.

On a somewhat related note: spawn and spawn' could benefit from running in MonadIO m, instead of just plain IO.

Gabriella439 commented 9 years ago

Note that if I'm going to incur an exceptions dependency then I would probably incur a managed dependency, too (both are equally lightweight dependencies in my eyes).

k0001 commented 9 years ago

Another interesting alternative would be to provide a version of withSpawn, named say withSpawn', that takes a bracketing function of type MonadIO m => m a -> (a -> m x) -> (a -> m b) -> m b, so that one can pick how to “bracket” this code.

withSpawn' Control.Exception.bracket 
    :: Buffer a 
    -> ((Output a, Input a) -> IO b) 
    -> IO b

withSpawn' Control.Monad.Catch.bracket
    :: (Monad IO, MonadMask m) 
    => Buffer a 
    -> ((Output a, Input a) -> m b) 
    -> m b

Maybe it's a good idea to provide this named withSpawn, and then have withSpawnIO be the version that fixes such m to IO.

Just throwing ideas here :)

Gabriella439 commented 9 years ago

The other benefit of adding managed is that actually managed could depend on exceptions and provide a MonadMask generalized version of with, which would be much more reusable.

k0001 commented 9 years ago

The other benefit of adding managed is that actually managed could depend on exceptions and provide a MonadMask generalized version of with, which would be much more reusable.

Ah, yes, I think that would benefit managed and encourage its usage.

sboosali commented 8 years ago

Are you still planning on adding the exceptions dependency to managed?

Gabriella439 commented 8 years ago

Actually, I'm not sure if Managed can implement MonadCatch now that I think about it

sboosali commented 8 years ago

Yeah, Managed a is forall r. ContT r IO a. I didn't see a ContT instance for MonadCatch (only ContT for MonadThrow). and bracket needs MonadMask, which makes sense.

I'm new to these resource-safety libraries, but I thought that the Rank2Type might change things (like a Void? or like ST? sorry, just being vague).

On Mon, Jun 13, 2016 at 3:53 AM, Gabriel Gonzalez notifications@github.com wrote:

Actually, I'm not sure if Managed can implement MonadCatch now that I think about it

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Gabriel439/Haskell-Pipes-Concurrency-Library/issues/35#issuecomment-225470588, or mute the thread https://github.com/notifications/unsubscribe/ACNoMdin1pNxuXihgE0d07tPHV_J51Oaks5qLKnvgaJpZM4DfuNa .

(this message was composed with dictation: charitably interpret typos)Sam Boosalis

Gabriella439 commented 8 years ago

In this case the more polymorphic type of Managed makes things harder because there are fewer valid ways we can write a Managed compared to ContT

On 06/13/2016 03:14 AM, Spiros Boosalis wrote:

Yeah, Managed a is forall r. ContT r IO a. I didn't see a ContT instance for MonadCatch (only ContT for MonadThrow). and bracket needs MonadMask, which makes sense.

I'm new to these resource-safety libraries, but I thought that the Rank2Type might change things (like a Void? or like ST? sorry, just being vague).

On Mon, Jun 13, 2016 at 3:53 AM, Gabriel Gonzalez notifications@github.com wrote:

Actually, I'm not sure if Managed can implement MonadCatch now that I think about it

— You are receiving this because you commented. Reply to this email directly, view it on GitHub

https://github.com/Gabriel439/Haskell-Pipes-Concurrency-Library/issues/35#issuecomment-225470588, or mute the thread

https://github.com/notifications/unsubscribe/ACNoMdin1pNxuXihgE0d07tPHV_J51Oaks5qLKnvgaJpZM4DfuNa .

(this message was composed with dictation: charitably interpret typos)Sam Boosalis

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Gabriel439/Haskell-Pipes-Concurrency-Library/issues/35#issuecomment-225541770, or mute the thread https://github.com/notifications/unsubscribe/ABQL-3Z0YG4iRl4ssf6bTb3AGfdIH_0lks5qLS1zgaJpZM4DfuNa.