Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Network.TypedProtocol.PingPong.Client
Contents
Synopsis
- data PingPongClient m a where
- SendMsgPing :: m (PingPongClient m a) -> PingPongClient m a
- SendMsgDone :: a -> PingPongClient m a
- pingPongClientPeer :: Monad m => PingPongClient m a -> Peer PingPong AsClient StIdle m a
- data PingPongClientPipelined m a where
- PingPongClientPipelined :: PingPongSender Z c m a -> PingPongClientPipelined m a
- data PingPongSender n c m a where
- SendMsgPingPipelined :: m c -> PingPongSender (S n) c m a -> PingPongSender n c m a
- CollectPipelined :: Maybe (PingPongSender (S n) c m a) -> (c -> PingPongSender n c m a) -> PingPongSender (S n) c m a
- SendMsgDonePipelined :: a -> PingPongSender Z c m a
- pingPongClientPeerPipelined :: Monad m => PingPongClientPipelined m a -> PeerPipelined PingPong AsClient StIdle m a
Normal client
data PingPongClient m a where Source #
A ping-pong client, on top of some effect m
.
At each step the client has a choice: ping or stop.
This type encodes the pattern of state transitions the client can go through. For the ping/pong case this is trivial. We start from one main state, issue a ping and move into a state where we expect a single response, bringing us back to the same main state.
If we had another state in which a different set of options were available then we would need a second type like this. The two would be mutually recursive if we can get in both directions, or perhaps just one way such as a special initialising state or special terminating state.
Constructors
SendMsgPing :: m (PingPongClient m a) -> PingPongClient m a | Choose to go for sending a ping message. The ping has no body so all we have to provide here is a continuation for the single legal reply message. |
SendMsgDone :: a -> PingPongClient m a | Choose to terminate the protocol. This is an actual but nullary message,
we terminate with the local result value. So this ends up being much like
|
pingPongClientPeer :: Monad m => PingPongClient m a -> Peer PingPong AsClient StIdle m a Source #
Interpret a particular client action sequence into the client side of the
PingPong
protocol.
Pipelined client
data PingPongClientPipelined m a where Source #
A ping-pong client designed for running the PingPong
protocol in
a pipelined way.
Constructors
PingPongClientPipelined :: PingPongSender Z c m a -> PingPongClientPipelined m a | A |
data PingPongSender n c m a where Source #
Constructors
SendMsgPingPipelined :: m c -> PingPongSender (S n) c m a -> PingPongSender n c m a | Send a |
CollectPipelined :: Maybe (PingPongSender (S n) c m a) -> (c -> PingPongSender n c m a) -> PingPongSender (S n) c m a | Collect the result of a previous pipelined receive action. This (optionally) provides two choices:
Since presenting the first choice is optional, this allows expressing both a blocking collect and a non-blocking collect. This allows implementations to express policies such as sending a short sequence of messages and then waiting for all replies, but also a maximum pipelining policy that keeps a large number of messages in flight but collects results eagerly. |
SendMsgDonePipelined :: a -> PingPongSender Z c m a | Termination of the ping-pong protocol. Note that all pipelined results must be collected before terminating. |
pingPongClientPeerPipelined :: Monad m => PingPongClientPipelined m a -> PeerPipelined PingPong AsClient StIdle m a Source #
Interpret a pipelined client as a PeerPipelined
on the client side of
the PingPong
protocol.