
Dear Haskellers, I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad. The short version is that forkable-monad exports a replacement forkIO that lets you do this: type MyMonad = ReaderT Config (StateT Ctx IO) startThread :: MyMonad ThreadId startThread = forkIO threadMain threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn "Painless monad stack forking!" Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module. forkable-monad is available: * On hackage: http://hackage.haskell.org/package/forkable-monad * Via cabal: cabal install forkable-monad * Source and issue tracker: http://code.google.com/p/forkable-monad/ Feedback is of course welcome. As this is my first published Haskell code and Hackage upload, I expect there will be quite a bit! - Dave

Hi, This is quite a neat generalisation of forkIO, and something I've wanted in the past. My comment would be about the MonadIO m requirement for ForkableMonad. I understand that conceptually it's a nice thing to have. But practically, I don't think it's necessary, and could be a little restrictive -- I could imagine potentially having a newtype-wrapped monad that doesn't have a MonadIO instance, but does have a ForkableMonad instance. I tried removing the MonadIO constraint, and it works as long as you add a Monad constraint either to the class or to the ReaderT and StateT instances. That depends if you can imagine an instance of ForkableMonad that wasn't a Monad (an applicative perhaps)... probably not, especially given the name. In short: I recommend changing MonadIO m to Monad m on the class. I came up with this instance for ContT: instance (ForkableMonad m) => ForkableMonad (ContT r m) where forkIO act = lift $ forkIO (runContT act (const $ return undefined)) I don't know if that's useful and/or correct, though. Thanks, Neil. David Anderson wrote:
Dear Haskellers,
I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad.
The short version is that forkable-monad exports a replacement forkIO that lets you do this:
type MyMonad = ReaderT Config (StateT Ctx IO)
startThread :: MyMonad ThreadId startThread = forkIO threadMain
threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn "Painless monad stack forking!"
Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module.
forkable-monad is available:
* On hackage: http://hackage.haskell.org/package/forkable-monad * Via cabal: cabal install forkable-monad * Source and issue tracker: http://code.google.com/p/forkable-monad/
Feedback is of course welcome. As this is my first published Haskell code and Hackage upload, I expect there will be quite a bit!
- Dave _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, Apr 21, 2010 at 4:39 PM, Neil Brown
Hi,
This is quite a neat generalisation of forkIO, and something I've wanted in the past.
My comment would be about the MonadIO m requirement for ForkableMonad. I understand that conceptually it's a nice thing to have. But practically, I don't think it's necessary, and could be a little restrictive -- I could imagine potentially having a newtype-wrapped monad that doesn't have a MonadIO instance, but does have a ForkableMonad instance. I tried removing the MonadIO constraint, and it works as long as you add a Monad constraint either to the class or to the ReaderT and StateT instances. That depends if you can imagine an instance of ForkableMonad that wasn't a Monad (an applicative perhaps)... probably not, especially given the name.
In short: I recommend changing MonadIO m to Monad m on the class.
Hmm, I see. Originally I defined the MonadIO constraint because it seemed the best way to state that the monad stack should have IO at its core, to allow for calling the classic forkIO at some point. That said, the argument for a newtyped stack that doesn't implement MonadIO does make some sense. Change submitted and pushed at http://code.google.com/p/forkable-monad/source/detail?r=89 . Thanks!
I came up with this instance for ContT:
instance (ForkableMonad m) => ForkableMonad (ContT r m) where forkIO act = lift $ forkIO (runContT act (const $ return undefined))
I don't know if that's useful and/or correct, though.
Hmm. Good question. I haven't quite wrapped my head around ContT yet, but I'll make a note to meditate over your implementation. If it makes sense in the context of forking threads, I'll add it to the collection. Thanks again, - Dave
David Anderson wrote:
Dear Haskellers,
I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad.
The short version is that forkable-monad exports a replacement forkIO that lets you do this:
type MyMonad = ReaderT Config (StateT Ctx IO)
startThread :: MyMonad ThreadId startThread = forkIO threadMain
threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn "Painless monad stack forking!"
Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module.
forkable-monad is available:
* On hackage: http://hackage.haskell.org/package/forkable-monad * Via cabal: cabal install forkable-monad * Source and issue tracker: http://code.google.com/p/forkable-monad/
Feedback is of course welcome. As this is my first published Haskell code and Hackage upload, I expect there will be quite a bit!
- Dave _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

David Anderson wrote:
Dear Haskellers,
I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad.
The short version is that forkable-monad exports a replacement forkIO that lets you do this:
type MyMonad = ReaderT Config (StateT Ctx IO)
startThread :: MyMonad ThreadId startThread = forkIO threadMain
threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn "Painless monad stack forking!"
Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module.
Nice work! It appears to me that this is subsumed by the recent MonadMorphIO proposal that Anders Kaseorg came up with, though? http://article.gmane.org/gmane.comp.lang.haskell.libraries/12902 fork :: MonadMorphIO m => m () -> m () fork m = morphIO $ \down -> forkIO (down m >> return ()) >> down (return ()) Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

[-haskell]
On Wed, Apr 21, 2010 at 5:54 PM, Heinrich Apfelmus
David Anderson wrote:
Dear Haskellers,
I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad.
The short version is that forkable-monad exports a replacement forkIO that lets you do this:
type MyMonad = ReaderT Config (StateT Ctx IO)
startThread :: MyMonad ThreadId startThread = forkIO threadMain
threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn "Painless monad stack forking!"
Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module.
Nice work!
It appears to me that this is subsumed by the recent MonadMorphIO proposal that Anders Kaseorg came up with, though?
http://article.gmane.org/gmane.comp.lang.haskell.libraries/12902
fork :: MonadMorphIO m => m () -> m () fork m = morphIO $ \down -> forkIO (down m >> return ()) >> down (return ())
Hmm, quite possibly. It is also quite similar to another implementation of forkable monad stacks I came across after finishing this first version of the library, and to what I had tentatively called "unliftIO" with a slightly different type, in another experiment in messing with forking monad stacks. So, it seems that I am reinventing wheels that others have generalized better :-). That's fine, it's the expected result of launching and iterating, especially given my current command of Haskell. So I should now focus on reducing the reinvention. Most of the discussion that followed the message that you linked is currently beyond my understanding of category theory. However, I should probably go and talk to the maintainer of MonadCatchIO-* about extracting something like MonadMorphIO into a package, and making both their exception handling modules and this forking module reuse it. Thanks for the pointer! - Dave
Regards, Heinrich Apfelmus
-- http://apfelmus.nfshost.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

David Anderson wrote:
So, it seems that I am reinventing wheels that others have generalized better :-). That's fine, it's the expected result of launching and iterating, especially given my current command of Haskell. So I should now focus on reducing the reinvention.
No worries, this MonadMorphIO thing is very recent, I just wanted to mention that it's applicable here as well. :)
Most of the discussion that followed the message that you linked is currently beyond my understanding of category theory. However, I should probably go and talk to the maintainer of MonadCatchIO-* about extracting something like MonadMorphIO into a package, and making both their exception handling modules and this forking module reuse it.
Sounds good; although I do think that the problem of making monads modular does not yet have a completely satisfactory answer, even with MonadMorphIO. But that should not deter from experimentation. :) Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (3)
-
David Anderson
-
Heinrich Apfelmus
-
Neil Brown