{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Network.TypedProtocol.PingPong.Client
(
PingPongClient (..)
, pingPongClientPeer
, PingPongClientPipelined (..)
, PingPongClientIdle (..)
, pingPongClientPeerPipelined
) where
import Network.TypedProtocol.Core
import Network.TypedProtocol.Peer.Client
import Network.TypedProtocol.PingPong.Type
data PingPongClient m a where
SendMsgPing :: m (PingPongClient m a)
-> PingPongClient m a
SendMsgDone :: a -> PingPongClient m a
pingPongClientPeer
:: Functor m
=> PingPongClient m a
-> Client PingPong NonPipelined StIdle m a
pingPongClientPeer :: forall (m :: * -> *) a.
Functor m =>
PingPongClient m a -> Client PingPong 'NonPipelined 'StIdle m a
pingPongClientPeer (SendMsgDone a
result) =
Message PingPong 'StIdle 'StDone
-> Client PingPong 'NonPipelined 'StDone m a
-> Client PingPong 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
(st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message PingPong 'StIdle 'StDone
MsgDone (a -> Client PingPong 'NonPipelined 'StDone m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'NobodyAgency,
Outstanding pl ~ 'Z) =>
a -> Client ps pl st m a
Done a
result)
pingPongClientPeer (SendMsgPing m (PingPongClient m a)
next) =
Message PingPong 'StIdle 'StBusy
-> Client PingPong 'NonPipelined 'StBusy m a
-> Client PingPong 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
(st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message PingPong 'StIdle 'StBusy
MsgPing (Client PingPong 'NonPipelined 'StBusy m a
-> Client PingPong 'NonPipelined 'StIdle m a)
-> Client PingPong 'NonPipelined 'StBusy m a
-> Client PingPong 'NonPipelined 'StIdle m a
forall a b. (a -> b) -> a -> b
$
(forall (st' :: PingPong).
Message PingPong 'StBusy st'
-> Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined 'StBusy m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: PingPong).
Message PingPong 'StBusy st'
-> Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined 'StBusy m a)
-> (forall (st' :: PingPong).
Message PingPong 'StBusy st'
-> Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined 'StBusy m a
forall a b. (a -> b) -> a -> b
$ \Message PingPong 'StBusy st'
R:MessagePingPongfromto 'StBusy st'
MsgPong ->
m (Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined st' m a)
-> m (Client PingPong 'NonPipelined st' m a)
-> Client PingPong 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ PingPongClient m a -> Client PingPong 'NonPipelined st' m a
PingPongClient m a -> Client PingPong 'NonPipelined 'StIdle m a
forall (m :: * -> *) a.
Functor m =>
PingPongClient m a -> Client PingPong 'NonPipelined 'StIdle m a
pingPongClientPeer (PingPongClient m a -> Client PingPong 'NonPipelined st' m a)
-> m (PingPongClient m a)
-> m (Client PingPong 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (PingPongClient m a)
next
data PingPongClientPipelined c m a where
PingPongClientPipelined ::
PingPongClientIdle Z c m a
-> PingPongClientPipelined c m a
data PingPongClientIdle (n :: N) c m a where
SendMsgPingPipelined
:: m c
-> PingPongClientIdle (S n) c m a
-> PingPongClientIdle n c m a
CollectPipelined
:: Maybe (PingPongClientIdle (S n) c m a)
-> (c -> (PingPongClientIdle n c m a))
-> PingPongClientIdle (S n) c m a
SendMsgDonePipelined
:: a -> PingPongClientIdle Z c m a
pingPongClientPeerPipelined
:: Functor m
=> PingPongClientPipelined c m a
-> ClientPipelined PingPong StIdle m a
pingPongClientPeerPipelined :: forall (m :: * -> *) c a.
Functor m =>
PingPongClientPipelined c m a
-> ClientPipelined PingPong 'StIdle m a
pingPongClientPeerPipelined (PingPongClientPipelined PingPongClientIdle 'Z c m a
peer) =
Client PingPong ('Pipelined 'Z c) 'StIdle m a
-> ClientPipelined PingPong 'StIdle m a
forall ps (st :: ps) (m :: * -> *) a c.
Client ps ('Pipelined 'Z c) st m a -> ClientPipelined ps st m a
ClientPipelined (Client PingPong ('Pipelined 'Z c) 'StIdle m a
-> ClientPipelined PingPong 'StIdle m a)
-> Client PingPong ('Pipelined 'Z c) 'StIdle m a
-> ClientPipelined PingPong 'StIdle m a
forall a b. (a -> b) -> a -> b
$ PingPongClientIdle 'Z c m a
-> Client PingPong ('Pipelined 'Z c) 'StIdle m a
forall (n :: N) c (m :: * -> *) a.
Functor m =>
PingPongClientIdle n c m a
-> Client PingPong ('Pipelined n c) 'StIdle m a
pingPongClientPeerIdle PingPongClientIdle 'Z c m a
peer
pingPongClientPeerIdle
:: forall (n :: N) c m a. Functor m
=> PingPongClientIdle n c m a
-> Client PingPong (Pipelined n c) StIdle m a
pingPongClientPeerIdle :: forall (n :: N) c (m :: * -> *) a.
Functor m =>
PingPongClientIdle n c m a
-> Client PingPong ('Pipelined n c) 'StIdle m a
pingPongClientPeerIdle = PingPongClientIdle n c m a
-> Client PingPong ('Pipelined n c) 'StIdle m a
forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
go
where
go :: forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong (Pipelined n' c) StIdle m a
go :: forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
go (SendMsgPingPipelined m c
receive PingPongClientIdle ('S n') c m a
next) =
Message PingPong 'StIdle 'StBusy
-> Receiver PingPong 'StBusy 'StIdle m c
-> Client PingPong ('Pipelined ('S n') c) 'StIdle m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
forall ps (st :: ps) (n :: N) c (m :: * -> *) a (st' :: ps)
(st'' :: ps).
(StateTokenI st, StateTokenI st',
StateAgency st ~ 'ClientAgency) =>
Message ps st st'
-> Receiver ps st' st'' m c
-> Client ps ('Pipelined ('S n) c) st'' m a
-> Client ps ('Pipelined n c) st m a
YieldPipelined
Message PingPong 'StIdle 'StBusy
MsgPing
((forall (st' :: PingPong).
Message PingPong 'StBusy st' -> Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong 'StBusy 'StIdle m c
forall ps (st :: ps) (stdone :: ps) (m :: * -> *) c.
(StateTokenI st, ActiveState st, StateAgency st ~ 'ServerAgency) =>
(forall (st' :: ps).
Message ps st st' -> Receiver ps st' stdone m c)
-> Receiver ps st stdone m c
ReceiverAwait ((forall (st' :: PingPong).
Message PingPong 'StBusy st' -> Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong 'StBusy 'StIdle m c)
-> (forall (st' :: PingPong).
Message PingPong 'StBusy st' -> Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong 'StBusy 'StIdle m c
forall a b. (a -> b) -> a -> b
$ \Message PingPong 'StBusy st'
R:MessagePingPongfromto 'StBusy st'
MsgPong ->
m (Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong st' 'StIdle m c
forall ps (st :: ps) (stdone :: ps) (m :: * -> *) c.
m (Receiver ps st stdone m c) -> Receiver ps st stdone m c
ReceiverEffect (m (Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong st' 'StIdle m c)
-> m (Receiver PingPong st' 'StIdle m c)
-> Receiver PingPong st' 'StIdle m c
forall a b. (a -> b) -> a -> b
$ c -> Receiver PingPong st' st' m c
c -> Receiver PingPong st' 'StIdle m c
forall ps (stdone :: ps) (m :: * -> *) c.
c -> Receiver ps stdone stdone m c
ReceiverDone (c -> Receiver PingPong st' 'StIdle m c)
-> m c -> m (Receiver PingPong st' 'StIdle m c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m c
receive)
(PingPongClientIdle ('S n') c m a
-> Client PingPong ('Pipelined ('S n') c) 'StIdle m a
forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
go PingPongClientIdle ('S n') c m a
next)
go (CollectPipelined Maybe (PingPongClientIdle ('S n) c m a)
mNone c -> PingPongClientIdle n c m a
collect) =
Maybe (Client PingPong ('Pipelined ('S n) c) 'StIdle m a)
-> (c -> Client PingPong ('Pipelined n c) 'StIdle m a)
-> Client PingPong ('Pipelined ('S n) c) 'StIdle m a
forall ps (st :: ps) (n :: N) c (m :: * -> *) a.
(StateTokenI st, ActiveState st) =>
Maybe (Client ps ('Pipelined ('S n) c) st m a)
-> (c -> Client ps ('Pipelined n c) st m a)
-> Client ps ('Pipelined ('S n) c) st m a
Collect
(PingPongClientIdle ('S n) c m a
-> Client PingPong ('Pipelined ('S n) c) 'StIdle m a
forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
go (PingPongClientIdle ('S n) c m a
-> Client PingPong ('Pipelined ('S n) c) 'StIdle m a)
-> Maybe (PingPongClientIdle ('S n) c m a)
-> Maybe (Client PingPong ('Pipelined ('S n) c) 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (PingPongClientIdle ('S n) c m a)
mNone)
(PingPongClientIdle n c m a
-> Client PingPong ('Pipelined n c) 'StIdle m a
forall (n' :: N).
PingPongClientIdle n' c m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
go (PingPongClientIdle n c m a
-> Client PingPong ('Pipelined n c) 'StIdle m a)
-> (c -> PingPongClientIdle n c m a)
-> c
-> Client PingPong ('Pipelined n c) 'StIdle m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> PingPongClientIdle n c m a
collect)
go (SendMsgDonePipelined a
result) =
Message PingPong 'StIdle 'StDone
-> Client PingPong ('Pipelined n' c) 'StDone m a
-> Client PingPong ('Pipelined n' c) 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
(st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield
Message PingPong 'StIdle 'StDone
MsgDone
(a -> Client PingPong ('Pipelined n' c) 'StDone m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'NobodyAgency,
Outstanding pl ~ 'Z) =>
a -> Client ps pl st m a
Done a
result)