Skip to content

Commit 6c6a8ce

Browse files
committed
typed-protocols: moved outstanding counter into IsPipelined kind
1 parent 148a91b commit 6c6a8ce

File tree

15 files changed

+134
-126
lines changed

15 files changed

+134
-126
lines changed

typed-protocols-examples/src/Network/TypedProtocol/Driver/Simple.hs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ runPeer
131131
=> Tracer m (TraceSendRecv ps)
132132
-> Codec ps failure m bytes
133133
-> Channel m bytes
134-
-> Peer ps pr 'NonPipelined Z st m a
134+
-> Peer ps pr 'NonPipelined st m a
135135
-> m (a, Maybe bytes)
136136
runPeer tracer codec channel peer =
137137
runPeerWithDriver driver peer
@@ -152,7 +152,7 @@ runPipelinedPeer
152152
=> Tracer m (TraceSendRecv ps)
153153
-> Codec ps failure m bytes
154154
-> Channel m bytes
155-
-> Peer ps pr ('Pipelined c) Z st m a
155+
-> Peer ps pr ('Pipelined Z c) st m a
156156
-> m (a, Maybe bytes)
157157
runPipelinedPeer tracer codec channel peer =
158158
runPipelinedPeerWithDriver driver peer
@@ -196,8 +196,8 @@ runConnectedPeers :: (MonadAsync m, MonadCatch m,
196196
=> m (Channel m bytes, Channel m bytes)
197197
-> Tracer m (Role, TraceSendRecv ps)
198198
-> Codec ps failure m bytes
199-
-> Peer ps pr 'NonPipelined Z st m a
200-
-> Peer ps (FlipAgency pr) 'NonPipelined Z st m b
199+
-> Peer ps pr 'NonPipelined st m a
200+
-> Peer ps (FlipAgency pr) 'NonPipelined st m b
201201
-> m (a, b)
202202
runConnectedPeers createChannels tracer codec client server =
203203
createChannels >>= \(clientChannel, serverChannel) ->
@@ -214,8 +214,8 @@ runConnectedPeersPipelined :: (MonadAsync m, MonadCatch m,
214214
=> m (Channel m bytes, Channel m bytes)
215215
-> Tracer m (PeerRole, TraceSendRecv ps)
216216
-> Codec ps failure m bytes
217-
-> Peer ps pr ('Pipelined c) Z st m a
218-
-> Peer ps (FlipAgency pr) 'NonPipelined Z st m b
217+
-> Peer ps pr ('Pipelined Z c) st m a
218+
-> Peer ps (FlipAgency pr) 'NonPipelined st m b
219219
-> m (a, b)
220220
runConnectedPeersPipelined createChannels tracer codec client server =
221221
createChannels >>= \(clientChannel, serverChannel) ->
@@ -240,8 +240,8 @@ runConnectedPeersAsymmetric
240240
-> Tracer m (Role, TraceSendRecv ps)
241241
-> Codec ps failure m bytes
242242
-> Codec ps failure m bytes
243-
-> Peer ps pr ('Pipelined c) Z st m a
244-
-> Peer ps (FlipAgency pr) 'NonPipelined Z st m b
243+
-> Peer ps pr ('Pipelined Z c) st m a
244+
-> Peer ps (FlipAgency pr) 'NonPipelined st m b
245245
-> m (a, b)
246246
runConnectedPeersAsymmetric createChannels tracer codec codec' client server =
247247
createChannels >>= \(clientChannel, serverChannel) ->

typed-protocols-examples/src/Network/TypedProtocol/PingPong/Client.hs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ data PingPongClient m a where
5454
pingPongClientPeer
5555
:: Functor m
5656
=> PingPongClient m a
57-
-> Client PingPong NonPipelined Z StIdle m a
57+
-> Client PingPong NonPipelined StIdle m a
5858

5959
pingPongClientPeer (SendMsgDone result) =
6060
-- We do an actual transition using 'yield', to go from the 'StIdle' to
@@ -94,7 +94,7 @@ data PingPongClientPipelined c m a where
9494
-> PingPongClientPipelined c m a
9595

9696

97-
data PingPongClientIdle (n :: Outstanding) c m a where
97+
data PingPongClientIdle (n :: N) c m a where
9898
-- | Send a `Ping` message but alike in `PingPongClient` do not await for the
9999
-- response, instead supply a monadic action which will run on a received
100100
-- `Pong` message.
@@ -139,20 +139,20 @@ data PingPongClientIdle (n :: Outstanding) c m a where
139139
pingPongClientPeerPipelined
140140
:: Functor m
141141
=> PingPongClientPipelined c m a
142-
-> Client PingPong (Pipelined c) Z StIdle m a
142+
-> Client PingPong (Pipelined Z c) StIdle m a
143143
pingPongClientPeerPipelined (PingPongClientPipelined peer) =
144144
pingPongClientPeerIdle peer
145145

146146

147147
pingPongClientPeerIdle
148-
:: forall (n :: Outstanding) c m a. Functor m
149-
=> PingPongClientIdle n c m a
150-
-> Client PingPong (Pipelined c) n StIdle m a
148+
:: forall (n :: N) c m a. Functor m
149+
=> PingPongClientIdle n c m a
150+
-> Client PingPong (Pipelined n c) StIdle m a
151151
pingPongClientPeerIdle = go
152152
where
153-
go :: forall (n' :: Outstanding).
154-
PingPongClientIdle n' c m a
155-
-> Client PingPong (Pipelined c) n' StIdle m a
153+
go :: forall (n' :: N).
154+
PingPongClientIdle n' c m a
155+
-> Client PingPong (Pipelined n' c) StIdle m a
156156

157157
go (SendMsgPingPipelined receive next) =
158158
-- Pipelined yield: send `MsgPing`, immediately follow with the next step.

typed-protocols-examples/src/Network/TypedProtocol/PingPong/Server.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ data PingPongServer m a = PingPongServer {
2626
pingPongServerPeer
2727
:: Monad m
2828
=> PingPongServer m a
29-
-> Server PingPong NonPipelined Z StIdle m a
29+
-> Server PingPong NonPipelined StIdle m a
3030
pingPongServerPeer PingPongServer{..} =
3131

3232
-- In the 'StIdle' the server is awaiting a request message

typed-protocols-examples/src/Network/TypedProtocol/ReqResp/Client.hs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ data ReqRespClient req resp m a where
3737
reqRespClientPeer
3838
:: Monad m
3939
=> ReqRespClient req resp m a
40-
-> Client (ReqResp req resp) NonPipelined Z StIdle m a
40+
-> Client (ReqResp req resp) NonPipelined StIdle m a
4141

4242
reqRespClientPeer (SendMsgDone result) =
4343
-- We do an actual transition using 'yield', to go from the 'StIdle' to
@@ -68,7 +68,7 @@ reqRespClientPeer (SendMsgReq req next) =
6868

6969
requestOnce :: forall req resp m.
7070
Monad m
71-
=> (forall x. Server (ReqResp req resp) NonPipelined Z StIdle m x)
71+
=> (forall x. Server (ReqResp req resp) NonPipelined StIdle m x)
7272
-> (req -> m resp)
7373
requestOnce server req = (\(resp, _, _) -> resp)
7474
<$> reqRespClientPeer client `connect` server
@@ -88,52 +88,52 @@ data ReqRespClientPipelined req resp c m a where
8888
-- | A 'PingPongSender', but starting with zero outstanding pipelined
8989
-- responses, and for any internal collect type @c@.
9090
ReqRespClientPipelined ::
91-
ReqRespIdle req resp c Z m a
92-
-> ReqRespClientPipelined req resp c m a
91+
ReqRespIdle req resp Z c m a
92+
-> ReqRespClientPipelined req resp c m a
9393

9494

95-
data ReqRespIdle req resp c n m a where
95+
data ReqRespIdle req resp n c m a where
9696
-- | Send a `Req` message but alike in `ReqRespClient` do not await for the
9797
-- resopnse, instead supply a monadic action which will run on a received
9898
-- `Pong` message.
9999
SendMsgReqPipelined
100100
:: req
101101
-> (resp -> m c) -- receive action
102-
-> ReqRespIdle req resp c (S n) m a -- continuation
103-
-> ReqRespIdle req resp c n m a
102+
-> ReqRespIdle req resp (S n) c m a -- continuation
103+
-> ReqRespIdle req resp n c m a
104104

105105
CollectPipelined
106-
:: Maybe (ReqRespIdle req resp c (S n) m a)
107-
-> (c -> m (ReqRespIdle req resp c n m a))
108-
-> ReqRespIdle req resp c (S n) m a
106+
:: Maybe (ReqRespIdle req resp (S n) c m a)
107+
-> (c -> m (ReqRespIdle req resp n c m a))
108+
-> ReqRespIdle req resp (S n) c m a
109109

110110
-- | Termination of the req-resp protocol.
111111
SendMsgDonePipelined
112-
:: a -> ReqRespIdle req resp c Z m a
112+
:: a -> ReqRespIdle req resp Z c m a
113113

114114

115115
-- | Interpret a pipelined client as a 'Peer' on the client side of
116116
-- the 'ReqResp' protocol.
117117
--
118118
reqRespClientPeerPipelined
119119
:: Functor m
120-
=> ReqRespClientPipelined req resp c m a
121-
-> Client (ReqResp req resp) (Pipelined c) Z StIdle m a
120+
=> ReqRespClientPipelined req resp c m a
121+
-> Client (ReqResp req resp) (Pipelined Z c) StIdle m a
122122
reqRespClientPeerPipelined (ReqRespClientPipelined peer) =
123123
reqRespClientPeerIdle peer
124124

125125

126126
reqRespClientPeerIdle
127127
:: forall req resp n c m a.
128128
Functor m
129-
=> ReqRespIdle req resp c n m a
130-
-> Client (ReqResp req resp) (Pipelined c) n StIdle m a
129+
=> ReqRespIdle req resp n c m a
130+
-> Client (ReqResp req resp) (Pipelined n c) StIdle m a
131131

132132
reqRespClientPeerIdle = go
133133
where
134134
go :: forall n'.
135-
ReqRespIdle req resp c n' m a
136-
-> Client (ReqResp req resp) (Pipelined c) n' StIdle m a
135+
ReqRespIdle req resp n' c m a
136+
-> Client (ReqResp req resp) (Pipelined n' c) StIdle m a
137137

138138
go (SendMsgReqPipelined req receive next) =
139139
-- Pipelined yield: send `MsgReq`, immediately follow with the next step.

typed-protocols-examples/src/Network/TypedProtocol/ReqResp/Examples.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ reqRespClientMapPipelined :: forall req resp m.
7272
reqRespClientMapPipelined reqs0 =
7373
ReqRespClientPipelined (go [] Zero reqs0)
7474
where
75-
go :: [resp] -> Nat o -> [req] -> ReqRespIdle req resp resp o m [resp]
75+
go :: [resp] -> Nat o -> [req] -> ReqRespIdle req resp o resp m [resp]
7676
go resps Zero reqs =
7777
case reqs of
7878
[] -> SendMsgDonePipelined (reverse resps)
@@ -86,7 +86,7 @@ reqRespClientMapPipelined reqs0 =
8686
(\resp -> return $ go (resp:resps) o reqs)
8787

8888
sendReq :: [resp] -> Nat o -> req -> [req]
89-
-> ReqRespIdle req resp resp o m [resp]
89+
-> ReqRespIdle req resp o resp m [resp]
9090
sendReq resps o req reqs' =
9191
SendMsgReqPipelined req
9292
(\resp -> return resp)

typed-protocols-examples/src/Network/TypedProtocol/ReqResp/Server.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ data ReqRespServer req resp m a = ReqRespServer {
2626
reqRespServerPeer
2727
:: Monad m
2828
=> ReqRespServer req resp m a
29-
-> Server (ReqResp req resp) NonPipelined Z StIdle m a
29+
-> Server (ReqResp req resp) NonPipelined StIdle m a
3030
reqRespServerPeer ReqRespServer{..} =
3131

3232
-- In the 'StIdle' the server is awaiting a request message

typed-protocols-examples/src/Network/TypedProtocol/ReqResp2/Client.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ import Network.TypedProtocol.Peer.Client
1818
reqResp2Client :: forall req resp m.
1919
()
2020
=> [Either req req]
21-
-> Client (ReqResp2 req resp) (Pipelined (Either resp resp)) Z StIdle m [Either resp resp]
21+
-> Client (ReqResp2 req resp) (Pipelined Z (Either resp resp)) StIdle m [Either resp resp]
2222
reqResp2Client = send Zero
2323
where
2424
-- pipeline all the requests, either through `MsgReq` or `MsgReq'`.
2525
send :: forall (n :: N).
2626
Nat n
2727
-> [Either req req] -- requests to send
28-
-> Client (ReqResp2 req resp) (Pipelined (Either resp resp)) n StIdle m [Either resp resp]
28+
-> Client (ReqResp2 req resp) (Pipelined n (Either resp resp)) StIdle m [Either resp resp]
2929

3030
send !n (Left req : reqs) =
3131
YieldPipelined (MsgReq req) receiver (send (Succ n) reqs)
@@ -47,7 +47,7 @@ reqResp2Client = send Zero
4747
-- collect all the responses
4848
collect :: Nat n
4949
-> [Either resp resp] -- all the responses received so far
50-
-> Client (ReqResp2 req resp) (Pipelined (Either resp resp)) n StIdle m [Either resp resp]
50+
-> Client (ReqResp2 req resp) (Pipelined n (Either resp resp)) StIdle m [Either resp resp]
5151

5252
collect Zero !resps = Yield MsgDone (Done (reverse resps))
5353

typed-protocols-examples/src/Network/TypedProtocol/Trans/Wedge.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ type PingPong2 = Wedge PingPong.PingPong PingPong.StIdle
109109
PingPong.PingPong PingPong.StIdle
110110

111111

112-
pingPong2Client :: Client.Client PingPong2 NonPipelined Client.Z StIdle m ()
112+
pingPong2Client :: Client.Client PingPong2 NonPipelined StIdle m ()
113113
pingPong2Client =
114114
Client.Yield (MsgStart AtFst)
115115
$ Client.Yield (MsgFst PingPong.MsgPing)
@@ -122,7 +122,7 @@ pingPong2Client =
122122
$ Client.Done ()
123123

124124

125-
pingPong2Client' :: forall m. Client.Client PingPong2 (Pipelined ()) Client.Z StIdle m ()
125+
pingPong2Client' :: forall m. Client.Client PingPong2 (Pipelined Client.Z ()) StIdle m ()
126126
pingPong2Client' =
127127
--
128128
-- Pipeline first protocol

typed-protocols-examples/test/Network/TypedProtocol/ReqResp/Tests.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ directPipelined (ReqRespClientPipelined client0) server0 =
112112
where
113113
go :: forall n.
114114
Queue n c
115-
-> ReqRespIdle req resp c n m a
115+
-> ReqRespIdle req resp n c m a
116116
-> ReqRespServer req resp m b
117117
-> m (a, b)
118118
go EmptyQ (SendMsgDonePipelined clientResult) ReqRespServer{recvMsgDone} =

typed-protocols/src/Network/TypedProtocol/Core.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ module Network.TypedProtocol.Core
4141
, NobodyHasAgencyProof
4242
, FlipAgency
4343
, IsPipelined (..)
44+
, Outstanding
45+
, N (..)
4446
, ActiveAgency
4547
, ActiveAgency' (..)
4648
, IsActiveState (..)
@@ -478,13 +480,27 @@ type family FlipAgency pr where
478480
FlipAgency AsServer = AsClient
479481

480482

483+
-- | A type level inductive natural number.
484+
data N = Z | S N
485+
481486
-- | Promoted data type which indicates if 'Peer' is used in
482487
-- pipelined mode or not.
483488
--
484489
data IsPipelined where
485490
-- | Pipelined peer which is using `c :: Type` for collecting responses
486491
-- from a pipelined messages.
487-
Pipelined :: Type -> IsPipelined
492+
Pipelined :: N -> Type -> IsPipelined
488493

489494
-- | Non-pipelined peer.
490495
NonPipelined :: IsPipelined
496+
497+
-- | Type level count of the number of outstanding pipelined yields for which
498+
-- we have not yet collected a receiver result. Used in 'PeerSender' to ensure
499+
-- 'SenderCollect' is only used when there are outstanding results to collect,
500+
-- and to ensure 'SenderYield', 'SenderAwait' and 'SenderDone' are only used
501+
-- when there are none.
502+
--
503+
type Outstanding :: IsPipelined -> N
504+
type family Outstanding pl where
505+
Outstanding 'NonPipelined = Z
506+
Outstanding ('Pipelined n _) = n

0 commit comments

Comments
 (0)