packages feed

simple-actors 0.1.0 → 0.2.0

raw patch · 3 files changed

+81/−44 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Concurrent.Actors: printB :: (Show s, Num n) => n -> Behavior s
+ Control.Concurrent.Actors: printB :: (Show s, Eq n, Num n) => n -> Behavior s
- Control.Concurrent.Actors: putStrB :: Num n => n -> Behavior String
+ Control.Concurrent.Actors: putStrB :: (Eq n, Num n) => n -> Behavior String

Files

Control/Concurrent/Actors.lhs view
@@ -68,7 +68,30 @@ >     -} > >     -- * Actor Behaviors+>     {- | +>     In the Actor Model, at each step an actor...+>     +>         - processes a single 'received' message+>         +>         - may 'spawn' new actors+>         +>         - may 'send' messages to other actors+>         +>         - 'return's the 'Behavior' for processing the /next/ message+>     +>     These actions take place within the @Action i@ monad, where @i@ is the type+>     of the input message the actor receives.+>     +>     /N.B.:/ the MonadIO instance here is an abstraction leak. An example of a+>     good use of 'liftIO' might be to give an @Action@ access to a source of+>     randomness.+>     -} >       Action()+>     {- | +>     An actor is created by 'spawn'ing a @Behavior@. Behaviors consist of a+>     composed 'Action' that is executed when a message is 'received' and+>     returns the @Behavior@ for processing the next input.+>     -} >     , Behavior(..) >     -- ** Composing Behaviors >     , (<.|>)@@ -83,11 +106,11 @@ >     {- |  >     The 'spawn' function will be sufficient for forking actors in most cases, >     but launching mutually-communicating actors presents a problem.->     .+>       >     In cases where a 'Behavior' needs access to its own 'Mailbox' or that of  >     an actor that must be forked later, the 'MonadFix' instance should be >     used. GHC\'s \"Recursive Do\" make this especially easy:->     .+>       >     > {-# LANGUAGE DoRec #-} >     > beh = Receive $ do >     >     i <- received@@ -99,7 +122,9 @@ >     >     send b3 i >     >     send "first" b2 >     >     yield+> >     -}+> >     , spawn >     , spawn_ >     , spawnReading@@ -107,7 +132,7 @@ >     {- |  >     An actor computation can be halted immediately by calling 'yield', >     a synonym for 'mzero'. When an 'Action' calling @yield@ is composed with->     another using @<|>@ the second takes over processing the /same/ input+>     another using @\<|\>@ the second takes over processing the /same/ input >     which the former @yield@-ed on. > >     Here is an example of a computation using 'guard' which returns @mzero@ if@@ -129,6 +154,9 @@ >     , receive > >     -- * Utility functions+>     {- | +>     These are useful for debugging 'Behavior's+>     -} >     , runBehavior_ >     , runBehavior  >@@ -171,13 +199,22 @@  TODO ------- 0.2.0:+ 0.3.0:+    - define natural transformation combinators (in IO unfortunately) a.la.+      'categories' for Mailbox. So+        - :: Mailbox (a,b) -> (Mailbox a, Mailbox b)  -- divide?+        - :: Mailbox a -> Mailbox b -> Mailbox (Either a b) -- add?+        - etc...+      put these in a separate sub-module, optionally import, mention how an+      extension to actor model or something+    - allow supplying the first input message for an actor during spawn. This is+      awkward otherwise. Include in same sub-module as above?     - performance testing:         - take a look at threadscope for random tree test         - get complete code coverage into simple test module-    - interesting: http://en.wikipedia.org/wiki/Huang%27s_algorithm-    - better method for waiting for threads to complete. should probbly use+    - interesting solution to exit detection: +        http://en.wikipedia.org/wiki/Huang%27s_algorithm+    - better method for waiting for threads to complete. should probably use        actor message passing     - look into whether we should use Text lib instead of strings?       OverloadedStrings?@@ -185,27 +222,39 @@         -test if this lets us use it in importing module w/ OverloadedStrings         extension     - structured declarative and unit tests-    - Performance testing:-        - test performance vs. straight Chans, etc.-        - test out overhead of our various locks, especially difference if we-          scrap the snederLockMutex     - some sort of exception handling technique via Actors         (look at enumerator package)-    - investigate ways of positively influencing thread scheduling based on-       actor work agenda      - strict send' function-    -Behavior -> enumeratee package translator (and vice versa)-        (maybe letting us use useful enumerators)++Later:+    - investigate ways of positively influencing thread scheduling based on+       actor work agenda?     - export some more useful Actors and global thingies         - 'loop' which keeps consuming (is this provided by a class?)         - function returning an actor to "load balance" inputs over multiple           actors         - an actor that sends a random stream?         - a pre-declared Mailbox for IO?++ Eventualy:     - provide an "adapter" for amazon SQS, allowing truly distributed message       passing--+    - investigate erlang-style selective receive (using Alternative?)+    - consider: combining TChans, where values are popped off when available,+      for chan-split?+    - look at ways we can represent network IO as channels to interface with+      this. E.g:+        - https://github.com/ztellman/aleph+        - http://akka.io/ (scala remote actors lib)+        - http://www.zeromq.org/intro:read-the-manual+        - interface to amazon SQS+        - http://msgpack.org/ +        - "shared memory" approaches?+        - cloudhaskell, haskell-mpi, etc. see: +            http://stackoverflow.com/questions/8362998/distributed-haskell-state-of-the-art-in-2011+    -Behavior -> enumeratee package translator (and vice versa)+        (maybe letting us use useful enumerators)+     ...also now pipes, conduits, etc. etc.   CHAN TYPES@@ -277,7 +326,9 @@ > -- >         send out (b,a) > -- >         return (pairUp out) > ---> -- Defined: @receive = return . Receive@+> -- Defined as: +> --+> -- > receive = return . Receive > receive :: Action i (Behavior i) -> Action i (Behavior i) > receive = return . Receive @@ -297,7 +348,7 @@ > -- | Send a message asynchronously. This can be used to send messages to other > -- Actors via a 'Mailbox', or used as a means of output from the Actor system > -- to IO since the function is polymorphic.-> -- .+> --   > -- > send b = liftIO . writeChan b > send :: (MonadIO m, SplitChan c x)=> c a -> a -> m () > send b = liftIO . writeChan b@@ -328,7 +379,6 @@ > runBehavior_ b = runBehavior b [(),()..] > > -- | run a 'Behavior' in the IO monad, taking its \"messages\" from the list.-> -- Useful for debugging @Behaviors@. > runBehavior :: Behavior a -> [a] -> IO () > runBehavior b (a:as) = runBehaviorStep b a >>= F.mapM_ (`runBehavior` as) > runBehavior _ _      = return ()@@ -360,7 +410,7 @@  > -- | Prints all messages to STDOUT in the order they are received, > -- 'yield'-ing /immediately/ after @n@ inputs are printed.-> printB :: (Show s, Num n)=> n -> Behavior s+> printB :: (Show s, Eq n, Num n)=> n -> Behavior s > printB = contramap (unlines . return . show) . putStrB  We want to yield right after printing the last input to print. This lets us@@ -375,7 +425,7 @@ For now we allow negative  > -- | Like 'printB' but using @putStr@.-> putStrB :: (Num n)=> n -> Behavior String+> putStrB :: (Eq n, Num n)=> n -> Behavior String > putStrB 0 = mempty --special case when called directly w/ 0 > putStrB n = Receive $ do >     s <- received@@ -392,7 +442,7 @@  > -- | A @Behavior@ that discard its first input, returning the passed Behavior > -- for processing subsequent inputs. Useful with 'Alternative' or 'Monoid'-> -- compositions when one wants to ignore the leftover input.+> -- compositions when one wants to ignore the leftover 'yield'ed message. > -- > -- > constB = Receive . return > constB :: Behavior i -> Behavior i
Control/Concurrent/Actors/Behavior.lhs view
@@ -29,9 +29,6 @@ A Behavior wraps an Action i a, into a list-like sequence of actions to perform over inputs: -> -- | An actor is created by 'spawn'ing a @Behavior@. Behaviors consist of-> -- a composed 'Action' that is executed when a message is 'received' and-> -- returns the @Behavior@ for processing the next input. > newtype Behavior i = Receive { headAction :: Action i (Behavior i) } >  > instance Contravariant Behavior where@@ -42,7 +39,7 @@ This is essentially a marriage of the Monoid [] instance with Action's Alternative instance, and I am mostly convinced it is right and has utility: -> -- | @b1 `mplus` b2@ has the 'headAction' of @b2@ begin where the 'abort'+> -- | @b1 `mplus` b2@ has the 'headAction' of @b2@ begin where the 'yield' > -- occured in @b1@, i.e. @b2@\'s first input will be the final input handed to > -- @b1@. > instance Monoid (Behavior i) where@@ -57,22 +54,6 @@ will be useful:  -> -- | In the Actor Model, at each step an actor...-> ---> --     - processes a single 'received' message-> --     -> --     - may 'spawn' new actors-> --     -> --     - may 'send' messages to other actors-> --     -> --     - 'return's the 'Behavior' for processing the /next/ message-> ---> -- These actions take place within the @Action i@ monad, where @i@ is the type-> -- of the input message the actor receives.-> ---> -- /N.B.:/ the MonadIO instance here is an abstraction leak. An example of a-> -- good use of 'liftIO' might be to give an @Action@ access to a source of-> -- randomness. > newtype Action i a = Action { readerT :: ReaderT i (MaybeT IO) a } >         deriving (Monad, MonadIO, MonadPlus, MonadReader i, >                   Functor, Applicative, Alternative, MonadFix)
simple-actors.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version:             0.1.0+Version:             0.2.0  -- A short (one-line) description of the package. Synopsis:            A library for more structured concurrent programming, based@@ -20,6 +20,12 @@                      Model. Computations are structured as "Behaviors" which take a                      single input value, perform some 'Action's, and return the                      Behavior to process the next input message it receives.+                     .+                     /CHANGES/ 0.1 - 0.2:+                     .+                     - documentation cleanup+                     .+                     - updates for GHC 7.4.1  -- The license under which the package is released. License:             BSD3