{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} module Network.TypedProtocol.Stateful.ReqResp.Client ( ReqRespClient (..) , reqRespClientPeer ) where import Data.Typeable import Network.TypedProtocol.Stateful.Peer.Client import Network.TypedProtocol.Stateful.ReqResp.Type data ReqRespClient req m a where SendMsgReq :: Typeable resp => req resp -> (resp -> m (ReqRespClient req m a)) -> ReqRespClient req m a SendMsgDone :: a -> ReqRespClient req m a reqRespClientPeer :: Monad m => ReqRespClient req m a -> Client (ReqResp req) StIdle State m a reqRespClientPeer :: forall (m :: * -> *) (req :: * -> *) a. Monad m => ReqRespClient req m a -> Client (ReqResp req) 'StIdle State m a reqRespClientPeer (SendMsgDone a a) = State 'StIdle -> State 'StDone -> Message (ReqResp req) 'StIdle 'StDone -> Client (ReqResp req) 'StDone State m a -> Client (ReqResp req) 'StIdle State m a forall ps (st :: ps) (f :: ps -> *) (m :: * -> *) a (st' :: ps). (StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency) => f st -> f st' -> Message ps st st' -> Client ps st' f m a -> Client ps st f m a Yield State 'StIdle forall {req :: * -> *}. State 'StIdle StateIdle State 'StDone forall {req :: * -> *}. State 'StDone StateDone Message (ReqResp req) 'StIdle 'StDone forall (req :: * -> *). Message (ReqResp req) 'StIdle 'StDone MsgDone (a -> Client (ReqResp req) 'StDone State m a forall ps (st :: ps) (f :: ps -> *) (m :: * -> *) a. (StateTokenI st, StateAgency st ~ 'NobodyAgency) => a -> Client ps st f m a Done a a) reqRespClientPeer (SendMsgReq req resp req resp -> m (ReqRespClient req m a) next) = State 'StIdle -> State ('StBusy resp) -> Message (ReqResp req) 'StIdle ('StBusy resp) -> Client (ReqResp req) ('StBusy resp) State m a -> Client (ReqResp req) 'StIdle State m a forall ps (st :: ps) (f :: ps -> *) (m :: * -> *) a (st' :: ps). (StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency) => f st -> f st' -> Message ps st st' -> Client ps st' f m a -> Client ps st f m a Yield State 'StIdle forall {req :: * -> *}. State 'StIdle StateIdle (req resp -> State ('StBusy resp) forall (req :: * -> *) result. Typeable result => req result -> State ('StBusy result) StateBusy req resp req) (req resp -> Message (ReqResp req) 'StIdle ('StBusy resp) forall resp (req :: * -> *). Typeable resp => req resp -> Message (ReqResp req) 'StIdle ('StBusy resp) MsgReq req resp req) (Client (ReqResp req) ('StBusy resp) State m a -> Client (ReqResp req) 'StIdle State m a) -> Client (ReqResp req) ('StBusy resp) State m a -> Client (ReqResp req) 'StIdle State m a forall a b. (a -> b) -> a -> b $ (forall (st' :: ReqResp req). State ('StBusy resp) -> Message (ReqResp req) ('StBusy resp) st' -> (Client (ReqResp req) st' State m a, State st')) -> Client (ReqResp req) ('StBusy resp) State m a forall ps (st :: ps) (f :: ps -> *) (m :: * -> *) a. (StateTokenI st, StateAgency st ~ 'ServerAgency) => (forall (st' :: ps). f st -> Message ps st st' -> (Client ps st' f m a, f st')) -> Client ps st f m a Await ((forall (st' :: ReqResp req). State ('StBusy resp) -> Message (ReqResp req) ('StBusy resp) st' -> (Client (ReqResp req) st' State m a, State st')) -> Client (ReqResp req) ('StBusy resp) State m a) -> (forall (st' :: ReqResp req). State ('StBusy resp) -> Message (ReqResp req) ('StBusy resp) st' -> (Client (ReqResp req) st' State m a, State st')) -> Client (ReqResp req) ('StBusy resp) State m a forall a b. (a -> b) -> a -> b $ \State ('StBusy resp) _ (MsgResp resp resp) -> let client :: m (ReqRespClient req m a) client = resp -> m (ReqRespClient req m a) next resp resp resp in ( m (Client (ReqResp req) st' State m a) -> Client (ReqResp req) st' State m a forall ps (st :: ps) (f :: ps -> *) (m :: * -> *) a. m (Client ps st f m a) -> Client ps st f m a Effect (m (Client (ReqResp req) st' State m a) -> Client (ReqResp req) st' State m a) -> m (Client (ReqResp req) st' State m a) -> Client (ReqResp req) st' State m a forall a b. (a -> b) -> a -> b $ ReqRespClient req m a -> Client (ReqResp req) st' State m a ReqRespClient req m a -> Client (ReqResp req) 'StIdle State m a forall (m :: * -> *) (req :: * -> *) a. Monad m => ReqRespClient req m a -> Client (ReqResp req) 'StIdle State m a reqRespClientPeer (ReqRespClient req m a -> Client (ReqResp req) st' State m a) -> m (ReqRespClient req m a) -> m (Client (ReqResp req) st' State m a) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m (ReqRespClient req m a) client , State st' State 'StIdle forall {req :: * -> *}. State 'StIdle StateIdle )