packages feed

ForkableT (empty) → 0.1.0.0

raw patch · 5 files changed

+119/−0 lines, 5 filesdep +basedep +monad-controldep +mtlsetup-changed

Dependencies added: base, monad-control, mtl, resourcet

Files

+ ForkableT.cabal view
@@ -0,0 +1,21 @@+-- Initial ForkableT.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                ForkableT+version:             0.1.0.0+synopsis:            Forkable monad transformers+description:         Provides two classes for modular handling of forking+license:             BSD3+license-file:        LICENSE+-- author:              +maintainer:          Andras Slemmer+-- copyright:           +category:            Control+build-type:          Simple+cabal-version:       >=1.8++library+  exposed-modules:     Control.Concurrent.ForkableT, Control.Concurrent.ForkableT.Instances+  -- other-modules:       +  build-depends:       base ==4.6.*, mtl ==2.1.*, monad-control ==0.3.*, resourcet ==0.4.*+  hs-source-dirs:      src
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, ++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of  nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Concurrent/ForkableT.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE DefaultSignatures, MultiParamTypeClasses, FlexibleContexts, Safe #-}+{-|+  This module defines two classes. @'Forkable' m n@ means a monad @n@ may be forked in @m@.+  @'ForkableT' t@ means that applying the transformer to @n@ and @m@ will mean you can still fork @t n@ in @t m@.++  The reason we need a separate class for monad transformers is because often times the \"forkability\" of a transformed monad does not depend on the underlying monad, only it's forkability. This is the case for example for most standard monad transformers.+-}+module Control.Concurrent.ForkableT+    (+      ForkableT(..)+    , Forkable(..)+    )+where++import Control.Concurrent+import Control.Monad.Reader+import Control.Monad.State+import Control.Monad.Error+import Control.Monad.Writer+import Control.Monad.Trans.Control++-- |ForkableT. The default instance uses 'MonadTransControl' to lift the underlying 'fork'+class ForkableT t where+    forkT :: (Forkable m n) => t n () -> t m ThreadId+    default forkT :: (MonadTransControl t, Forkable m n) => t n () -> t m ThreadId+    forkT t = liftWith $ \run -> fork $ run t >> return ()++-- |Forkable. The default instance uses 'ForkableT' and simply calls 'forkT'+class (MonadIO m, MonadIO n) => Forkable m n where+    fork :: n () -> m ThreadId+    default fork :: ForkableT t => t n () -> t m ThreadId+    fork = forkT++instance Forkable IO IO where+    fork = forkIO++instance ForkableT (ReaderT r)+instance ForkableT (StateT s)+instance (Monoid w) => ForkableT (WriterT w)+instance (Error e) => ForkableT (ErrorT e)+instance (Forkable m n) => Forkable (ReaderT r m) (ReaderT r n)+instance (Forkable m n) => Forkable (StateT s m) (StateT s n)+instance (Forkable m n, Error e) => Forkable (ErrorT e m) (ErrorT e n)++instance (Forkable m n) => Forkable (StateT s m) (ReaderT s n) where+    fork r = lift . runReaderT (fork r) =<< get+instance (Forkable m n) => Forkable (ReaderT s m) (StateT s n) where+    fork r = lift . evalStateT (fork r) =<< ask
+ src/Control/Concurrent/ForkableT/Instances.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts #-}+{-|+  This module defines non-Prelude 'Forkable'/'ForkableT' instances. It is separated from "Control.Concurrent.Forkable" because imported modules might not be -XSafe+-}+module Control.Concurrent.ForkableT.Instances+    ( module Control.Concurrent.ForkableT+    )+where++import Control.Concurrent.ForkableT++import Control.Monad.Trans.Control+import Control.Monad.Trans.Resource+import Control.Monad.State++-- ResourceT -should- be an instance of ForkableT, however the exposed functionality does not allow this for now.+instance (MonadBaseControl IO m, MonadIO m) => Forkable (ResourceT m) (ResourceT m) where+    fork = resourceForkIO