packages feed

eprocess (empty) → 1.0.0

raw patch · 5 files changed

+189/−0 lines, 5 filesdep +MonadCatchIO-mtldep +basedep +mtlsetup-changed

Dependencies added: MonadCatchIO-mtl, base, mtl

Files

+ LICENSE view
@@ -0,0 +1,31 @@+Copyright Fernando Brujo Benavides 2009++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 Fernando Brujo Benavides 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.+
+ README view
@@ -0,0 +1,2 @@+This library provides a *very* basic support for processes with message queues.  It was built using channels and MVars.+See http://hackage.haskell.org/package/eprocess
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ eprocess.cabal view
@@ -0,0 +1,32 @@+name: eprocess+version: 1.0.0+cabal-version: >=1.6+build-type: Simple+license: BSD3+license-file: LICENSE+copyright: 2009 Fernando "Brujo" Benavides+maintainer: greenmellon@gmail.com+stability: stable+package-url: http://code.haskell.org/eprocess+bug-reports: http://github.com/elbrujohalcon/eprocess/issues+synopsis: *Very* basic erlang-like process support for Haskel+description: This library provides a *very* basic support for processes with message queues.  It was built using channels and MVars.+category: Concurrency+author: Fernando "Brujo" Benavides+tested-with: GHC ==6.10.3, GHC ==6.10.4+data-files: LICENSE README+data-dir: ""+extra-source-files: Setup.hs+extra-tmp-files:++source-repository head+    type:     git+    location: git://github.com/elbrujohalcon/eprocess.git++Library+    build-depends: base >= 4,                   base < 5,+                   mtl >=1.1.0,                 mtl < 1.2,+                   MonadCatchIO-mtl >= 0.1.0,   MonadCatchIO-mtl < 0.3+    exposed-modules: Control.Concurrent.Process+    hs-source-dirs: src+    
+ src/Control/Concurrent/Process.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE GeneralizedNewtypeDeriving,+             MultiParamTypeClasses,+             FlexibleInstances,+             FunctionalDependencies,+             UndecidableInstances #-} ++-- | This module provides a *very* basic support for processes with message queues.  It was built using channels and MVars.+module Control.Concurrent.Process (+-- * Types+        ReceiverT, Handle, Process, +-- * Functions+-- ** Process creation +        makeProcess, runHere, spawn,+-- ** Message passing+        self, sendTo, recv, sendRecv+    ) where++import Control.Monad.Reader+import Control.Monad.State.Class+import Control.Monad.Writer.Class+import Control.Monad.Error.Class+import Control.Monad.CatchIO+import Data.Monoid+import Control.Concurrent+import Control.Concurrent.Chan++-- | A Process handle.  It's returned on process creation and should be used+-- | afterwards to send messages to it+newtype Handle r = PH {chan :: Chan r}++-- | The /ReceiverT/ generic type.+-- +-- [@r@] the type of things the process will receive+-- +-- [@m@] the monad in which it will run+-- +-- [@a@] the classic monad parameter+newtype ReceiverT r m a = RT { internalReader :: ReaderT (Handle r) m a }+    deriving (Monad, MonadIO, MonadTrans, MonadCatchIO)++-- | /Process/ are receivers that run in the IO Monad+type Process r = ReceiverT r IO++-- | /sendTo/ lets you send a message to a running process. Usage:+-- @+--      sendTo processHandle message+-- @+sendTo :: MonadIO m => Handle a -- ^ The receiver process handle +        -> a                    -- ^ The message to send+        -> m ()+sendTo ph = liftIO . writeChan (chan ph)++-- | /recv/ lets you receive a message in a running process (it's a blocking receive). Usage:+-- @+--      message <- recv+-- @+recv :: MonadIO m => ReceiverT r m r+recv = RT $ ask >>= liftIO . readChan . chan++-- | /sendRecv/ is just a syntactic sugar for:+-- @+--      sendTo h a >> recv+-- @ +sendRecv :: MonadIO m => Handle a -- ^ The receiver process handle+          -> a                    -- ^ The message to send+          -> ReceiverT r m r      -- ^ The process where this action is run will wait until it receives something+sendRecv h a = sendTo h a >> recv ++-- | /spawn/ starts a process and returns its handle. Usage:+-- @+--      handle <- spawn process+-- @+spawn :: MonadIO m => Process r k       -- ^ The process to be run+        -> m (Handle r)                 -- ^ The handle for that process+spawn p = liftIO $ do+                 pChan <- newChan+                 let handle = PH { chan = pChan }+                 let action = runReaderT (internalReader p) handle+                 forkIO $ action >> return ()+                 return handle++-- | /runHere/ executes process code in the current environment. Usage:+-- @+--      result <- runHere process+-- @+runHere :: MonadIO m => Process r t     -- ^ The process to be run+         -> m t                         -- ^ It's returned as an action+runHere p = liftIO (runReaderT (internalReader p) . PH =<< newChan)++-- | /self/ returns the handle of the current process. Usage:+-- @+--      handle <- self+-- @+self :: Monad m => ReceiverT r m (Handle r)+self = RT ask++-- | /makeProcess/ builds a process from a code that generates an IO action. Usage:+-- @+--      process <- makeProcess evalFunction receiver+-- @ +makeProcess :: (m t -> IO s) -> ReceiverT r m t -> Process r s +makeProcess f (RT a) = RT (mapReaderT f a)++instance MonadState s m => MonadState s (ReceiverT r m) where+    get = lift get+    put = lift . put++instance MonadReader r m => MonadReader r (ReceiverT r m) where+    ask = lift ask+    local = onInner . local ++instance (Monoid w, MonadWriter w m) => MonadWriter w (ReceiverT w m) where+    tell = lift . tell+    listen = onInner listen+    pass = onInner pass++instance MonadError e m => MonadError e (ReceiverT r m) where+    throwError = lift . throwError+    catchError (RT a) h = RT $ a `catchError` (\e -> internalReader $ h e)++onInner :: (m a -> m b) -> ReceiverT r m a -> ReceiverT r m b+onInner f (RT m) = RT $ mapReaderT f m