{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module Network.TypedProtocol.Stateful.ReqResp.Type where
import Data.Kind (Type)
import Data.Typeable
import Network.TypedProtocol.Core
type ReqResp :: (Type -> Type) -> Type
data ReqResp req where
StIdle :: ReqResp req
StBusy :: res
-> ReqResp req
StDone :: ReqResp req
type SReqResp :: ReqResp req -> Type
data SReqResp st where
SingIdle :: SReqResp StIdle
SingBusy :: SReqResp (StBusy res :: ReqResp req)
SingDone :: SReqResp StDone
deriving instance Show (SReqResp st)
instance StateTokenI StIdle where stateToken :: StateToken 'StIdle
stateToken = StateToken 'StIdle
SReqResp 'StIdle
forall {req :: * -> *}. SReqResp 'StIdle
SingIdle
instance StateTokenI (StBusy res) where stateToken :: StateToken ('StBusy res)
stateToken = StateToken ('StBusy res)
SReqResp ('StBusy res)
forall {res} (res :: res) (req :: * -> *). SReqResp ('StBusy res)
SingBusy
instance StateTokenI StDone where stateToken :: StateToken 'StDone
stateToken = StateToken 'StDone
SReqResp 'StDone
forall {req :: * -> *}. SReqResp 'StDone
SingDone
instance Protocol (ReqResp req) where
data Message (ReqResp req) from to where
MsgReq :: Typeable resp
=> req resp
-> Message (ReqResp req) StIdle (StBusy resp)
MsgResp :: Typeable resp
=> resp
-> Message (ReqResp req) (StBusy resp) StIdle
MsgDone :: Message (ReqResp req) StIdle StDone
type StateAgency StIdle = ClientAgency
type StateAgency (StBusy _) = ServerAgency
type StateAgency StDone = NobodyAgency
type StateToken = SReqResp
type State :: ReqResp req -> Type
data State st where
StateIdle :: State StIdle
StateBusy :: forall (req :: Type -> Type)
(result :: Type).
Typeable result
=> req result
-> State (StBusy result :: ReqResp req)
StateDone :: State StDone
type FileAPI :: Type -> Type
data FileAPI result where
ReadFile :: FilePath -> FileAPI String
WriteFile :: FilePath -> String -> FileAPI ()
type FileRPC = ReqResp FileAPI