This module provides Erlang like functionality for message passing.
Instead of mailboxes attached to each process you have to create the needed mailboxes yourself. This means that messages cannot be send to processes or threads directly, but only to mailboxes. On the other hand multiple threads may share a mailbox and one thread may have multiple mailboxes.
For a simple example on how to receive messages have a look at the
MsgHandler
type.
- class MailboxClass b where
- getMessage :: b m -> IO m
- unGetMessage :: b m -> m -> IO ()
- putMessage :: b m -> m -> IO ()
- isEmpty :: b m -> IO Bool
- close :: b m -> IO ()
- data Mailbox m
- newMailbox :: IO (Mailbox m)
- send :: MailboxClass b => b m -> m -> IO ()
- (<!) :: MailboxClass b => b m -> m -> IO ()
- receive :: MailboxClass b => b m -> [MsgHandler m a] -> IO a
- receiveNonBlocking :: MailboxClass b => b m -> [MsgHandler m a] -> IO a -> IO a
- receiveTimeout :: MailboxClass b => b m -> Int -> [MsgHandler m a] -> IO a -> IO a
- type MsgHandler m a = m -> Handler a
- data Handler a
- handler :: IO a -> Handler a
- (.>) :: MsgHandler m a -> (a -> b) -> MsgHandler m b
- (<|>) :: [MsgHandler m a] -> [MsgHandler m b] -> [MsgHandler m (Either a b)]
Mailbox
class MailboxClass b whereSource
Any instance of MailboxClass
may be used as a mailbox for message
passing. b
is the mailbox type and m is the message type.
:: b m | the mailbox |
-> IO m | the message |
Get a message from the mailbox (with Mailbox
it is the first one).
Put a message back to the mailbox (with Mailbox
it will be placed
at the beginning of the mailbox).
Add a new message to the mailbox (with Mailbox
it will be placed at
the end of the mailbox).
Checks wether the mailbox is empty.
Call this function to cleanup before exit or when the mailbox is no longer needed.
newMailbox :: IO (Mailbox m)Source
Creates a new mailbox.
Sending messages
:: MailboxClass b | |
=> b m | the mailbox |
-> m | the message |
-> IO () |
Send the given message to the given mailbox.
Receiving messages
:: MailboxClass b | |
=> b m | mailbox to receive on |
-> [MsgHandler m a] | message handlers |
-> IO a |
Receive messages in the flavour of Erlang's receive
.
For each message in the mailbox all message handlers are matched until a matching message is found. It will be removed from the mailbox and the matching message handler's action will be performed.
If no message matches any of the message handler, receive
will block and
check new incoming messages until a match is found.
:: MailboxClass b | |
=> b m | the mailbox |
-> [MsgHandler m a] | message handlers |
-> IO a | default handler |
-> IO a |
Like receive
, but doesn't block. If no match was found, the default
handler is executed.
:: MailboxClass b | |
=> b m | the mailbox |
-> Int | timeout in us |
-> [MsgHandler m a] | message handlers |
-> IO a | timeout handler |
-> IO a |
Like receive
, but times out after a given time. In case of timeout the
timeout handler is executed.
Message handlers
type MsgHandler m a = m -> Handler aSource
A function that matches a given message and returns the corresponding handler.
In case of an pattern matching error receive
will continue matching
the next MsgHandler
/ message.
For example you may write somthing like this:
receive mbox [ \ True -> handler $ return 1 , \ False -> handler $ return 2 ]
Message handler combinators
:: MsgHandler m a | message handler |
-> (a -> b) | function |
-> MsgHandler m b | new message handler |
Apply a function to the result of an message handler.
:: [MsgHandler m a] | message handlers |
-> [MsgHandler m b] | more message handlers |
-> [MsgHandler m (Either a b)] | combined message handlers |
Combine to lists of message handlers into one list. The results of the
message handler will be wrapped in Either
.