Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Implementing an actor.
Types/functions in this section help you implement the actor iteself.
The class of types that can act as the handle for an asynchronous actor.
An opaque data structure given to the actor that allows it to respond to a message.
Proof that respond
was called. Actor implementations can use this in
a type signature when they require that respond
be called at least
once, because calling respond
is the only way to generate values of
this type. For actors that respond to messages, this helps the compiler
ensure that a response is in fact generated for every case.
respond :: MonadIO m => Responder a -> a -> m Responded Source #
As an actor, respond to an asynchronous message.
Communicating with an actor.
These functions allow you to communicate with an actor.
:: (Actor actor, MonadIO m) | |
=> actor | The actor to which to send the message. |
-> (Responder a -> Msg actor) |
|
-> m a |
Send a message to an actor, and wait for a response.
The second argument, mkMessage
tells call
how to construct a message,
given a responder. You will typically want to package that responder into the
message itself, so that whatever actor is processing the messages has a way
to respond.
For instance, you message may look like this:
data Message = AddOne Int (Responder Int) | IntToString Int (Responder String)
Then you can use call
like so:
call actor (AddOne 1) :: IO Int call actor (IntToString 1) :: IO String
cast :: (Actor actor, MonadIO m) => actor -> Msg actor -> m () Source #
Send a message to an actor, but do not wait for a response.
Example.
This is an example actor that consist of a thread looping over the messages
received in a Chan
and responding to each one.
Note that Chan
is already an instance of Actor
.
import Control.Concurrent (forkIO) import OM.Actor (Responder, respond, call) data Message = AddOne Int (Responder Int) = IntToString Int (Responder String) startActor :: IO (Chan Message) startActor = do chan <- newChan forkIO (loop chan) return chan where loop :: Chan Message -> IO void loop chan = do readChan >>= handleMessage loop handleMessage :: Msg -> IO Responded handleMessage (AddOne n responder) = respond responder (n + 1) handleMessage (IntToString n responder) = respond responder (show n) main :: IO () main = do actor <- startActor print =<< call actor (AddOne 41) print =<< call actor (IntToString 42)