-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Session types library -- -- This packages provides a deep embedded domain-specific language for -- writing session typed program. A session typed program is a program -- annotated with session types. A session type describes a communication -- protocol at the type-level. The motivation for doing so is that it -- gives you a static guarantee that a program correctly implements a -- protocol. It may even guarantee that no deadlocking can occur. @package sessiontypes @version 0.1.0 -- | This module provides a collection of types and type families. -- -- Specifically it defines the session type data type, capability data -- type and type families that compute using session types or -- capabilities as arguments. module Control.SessionTypes.Types -- | The session type data type -- -- Each constructor denotes a specific session type. Using the -- DataKinds pragma the constructors are promoted to types and -- ST is promoted to a kind. data ST a -- | Send a value (:?>) :: a -> (ST a) -> ST a -- | Recv a value (:!>) :: a -> (ST a) -> ST a -- | Selection of branches Sel :: [ST a] -> ST a -- | Offering of branches Off :: [ST a] -> ST a -- | Delimit the scope of recursion R :: (ST a) -> ST a -- | Weaken the scope of recursion Wk :: (ST a) -> ST a -- | Recursion variable V :: ST a -- | End of the session Eps :: ST a -- | A capability that stores a context/scope that is a list of session -- types and a session type data Cap a Cap :: [ST a] -> (ST a) -> Cap a -- | Retrieves the session type from the capability -- | Retrieves the context from the capability -- | Type family for calculating the dual of a session type. It may be -- applied to a capability. -- -- We made Dual injective to support calculating the dual of a -- selection that contains an ambiguous branch. Of course that does -- require that the dual of that ambiguous branch must be known. -- | Type family for calculating the dual of a session type. It may be -- applied to the actual session type. -- | Type family for calculating the dual of a list of session types. -- | Type family for removing the send session type from the given session -- type. It may be applied to a capability. -- | Type family for removing the send session type from the given session -- type. It may be applied to a session type. -- | Type family for removing the send session type from a list of session -- types. -- | Type family for removing the receive session type from the given -- session type. It may be applied to a capability. -- | Type family for removing the receive session type from a list of -- session types. -- | Type family for removing the receive session type from the given -- session type. It may be applied to a session type. -- | Type family for applying a constraint to types of kind Type in -- a session type. It may be applied to a capability. -- | Type family for applying a constraint to types of kind Type in -- a list of session types. -- | Type family for applying a constraint to types of kind Type in -- a session type. It may be applied to a session type. -- | Type family for applying zero or more constraints to types of kind -- Type in a list of session types. It may be applied to a -- capability. -- | Promoted ifThenElse -- | Promoted not -- | Promoted || -- | Data type that takes a kind as an argument. Its sole constructor takes -- two capabilities parameterized by the kind argument. -- -- This data type is useful if it is necessary for an indexed monad to be -- indexed by four parameters. data Prod t (:*:) :: (Cap t) -> (Cap t) -> Prod t -- | Type family for returning the first argument of a product. -- | Type family for returning the second argument of a product. -- | Data type defining natural numbers data Nat Z :: Nat S :: Nat -> Nat -- | Data type that can give us proof of membership of an element in a list -- of elements. data Ref s xs [RefZ] :: Ref s (s : xs) [RefS] :: Ref s (k : xs) -> Ref s (t : (k : xs)) -- | Type family for computing which types in a list of types are equal to -- a given type. -- | Promoted ++ instance GHC.Classes.Ord Control.SessionTypes.Types.Nat instance GHC.Classes.Eq Control.SessionTypes.Types.Nat instance GHC.Show.Show Control.SessionTypes.Types.Nat -- | This module provides a set of indexed type classes (IxFunctor, -- IxApplicative, IxMonad, etc..) that correspond to existing type -- classes (Functor, Applicative, Monad, etc..) -- -- The intent of this module is to replace the use of non-indexed type -- classes with indexed type class. -- -- For that reason the indexed type classes expose functions that are -- named the same as the functions exposed by a corresponding non-indexed -- type class. -- -- There are two ways to use this module: -- --
-- import SessionTypes -- import qualified SessionTypes.Indexed as I -- -- prog = send 5 I.>> eps0 ---- --
-- {-# LANGUAGE RebindableSyntax #-}
-- import SessionTypes
-- import SessionTypes.Indexed
--
-- prog = do
-- send 5
-- eps0
--
--
-- With RebindableSyntax we construct a custom do notation by
-- rebinding (>>=) with (>>=) of IxMonad. Rebinding is
-- not limited to only (>>=), but also all other functions in
-- Prelude.
--
-- We do not want to force importing Prelude if you use
-- RebindableSyntax. Therefore this module also exports Prelude
-- that hides functions already defined by the indexed type classes.
module Control.SessionTypes.Indexed
class IxFunctor (f :: p -> p -> Type -> Type)
fmap :: IxFunctor f => (a -> b) -> f j k a -> f j k b
class IxFunctor f => IxApplicative (f :: p -> p -> Type -> Type)
pure :: IxApplicative f => a -> f i i a
(<*>) :: IxApplicative f => f s r (a -> b) -> f r k a -> f s k b
class IxApplicative m => IxMonad (m :: p -> p -> Type -> Type) where m1 >> m2 = m1 >>= \ _ -> m2 fail = error
(>>=) :: IxMonad m => m s t a -> (a -> m t k b) -> m s k b
(>>) :: IxMonad m => m s t a -> m t k b -> m s k b
return :: IxMonad m => a -> m i i a
fail :: IxMonad m => String -> m i i a
-- | Type class for lifting monadic computations
class IxMonad (t m) => IxMonadT t m
lift :: IxMonadT t m => m a -> t m s s a
-- | Type class for lifting indexed monadic computations
class IxMonad (t m) => IxMonadIxT t m
ilift :: IxMonadIxT t m => m s r a -> t m s r a
-- | Type class representing the indexed monad reader
class IxMonad m => IxMonadReader r m | m -> r
ask :: IxMonadReader r m => m s s r
local :: IxMonadReader r m => (r -> r) -> m s t a -> m s t a
reader :: IxMonadReader r m => (r -> a) -> m i i a
-- | Type class for indexed monads in which exceptions may be thrown.
class IxMonad m => IxMonadThrow m s
-- | Provide an Exception to be thrown
throwM :: (IxMonadThrow m s, Exception e) => e -> m s s a
-- | Type class for indexed monads to allow catching of exceptions.
class IxMonadThrow m s => IxMonadCatch m s
-- | Provide a handler to catch exceptions.
catch :: (IxMonadCatch m s, Exception e) => m s s a -> (e -> m s s a) -> m s s a
-- | Type class for indexed monads that may mask asynchronous exceptions.
class IxMonadCatch m s => IxMonadMask m s
-- | run an action that disables asynchronous exceptions. The provided
-- function can be used to restore the occurrence of asynchronous
-- exceptions.
mask :: IxMonadMask m s => ((m s s b -> m s s b) -> m s s b) -> m s s b
-- | Ensures that even interruptible functions may not raise asynchronous
-- exceptions.
uninterruptibleMask :: IxMonadMask m s => ((m s s b -> m s s b) -> m s s b) -> m s s b
-- | Type class for indexed monads that may lift IO computations.
class IxMonadIO m
liftIO :: IxMonadIO m => IO a -> m s s a
ap :: IxMonad m => m s r (a -> b) -> m r k a -> m s k b
ifThenElse :: Bool -> t -> t -> t
-- | This module provides an interface for writing session typed programs
module Control.SessionTypes.MonadSession
-- | The MonadSession type class exposes a set of functions that
-- composed together form a session typed program
--
-- A type that is an instance of MonadSession must therefore also
-- be an instance of IxMonad.
--
-- The functions themselves are generally defined as wrappers over
-- corresponding STTerm constructors.
class IxMonad m => MonadSession m
send :: MonadSession m => a -> m (Cap ctx (a :!> r)) (Cap ctx r) ()
recv :: MonadSession m => m (Cap ctx (a :?> r)) (Cap ctx r) a
sel1 :: MonadSession m => m (Cap ctx (Sel (s : xs))) (Cap ctx s) ()
sel2 :: MonadSession m => m (Cap ctx (Sel (s : (t : xs)))) (Cap ctx (Sel (t : xs))) ()
offZ :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx (Off '[s])) r a
offS :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx (Off (t : xs))) r a -> m (Cap ctx (Off (s : (t : xs)))) r a
recurse :: MonadSession m => m (Cap (s : ctx) s) r a -> m (Cap ctx (R s)) r a
weaken :: MonadSession m => m (Cap ctx s) r a -> m (Cap (t : ctx) (Wk s)) r a
var :: MonadSession m => m (Cap (s : ctx) s) r a -> m (Cap (s : ctx) V) r a
eps :: MonadSession m => a -> m (Cap ctx Eps) (Cap ctx Eps) a
-- | A session typed program that is polymorphic in its context can often
-- not be used by interpreters.
--
-- We can apply empty to the session typed program before passing
-- it to an interpreter to instantiate that the context is empty.
empty :: MonadSession m => m (Cap '[] s) r a -> m (Cap '[] s) r a
-- | Monadic composable definition of empty
--
-- Prefix a session typed program with (empty >>) to instantiate
-- the context to be empty.
empty0 :: MonadSession m => m (Cap '[] r) (Cap '[] r) ()
-- | Allows indexing of selections.
--
-- The given Ref type can be used as an indexed to select a
-- branch. This circumvents the need to sequence a bunch of sel1
-- and sel2 to select a branch.
--
--
-- prog :: MonadSession m => m ('Cap ctx (Sel '[a,b,c,d])) ('Cap ctx Eps) ()
--
-- MonadSession m => m ('Cap ctx b) ('Cap ctx Eps) ()
-- prog2 = prog >> selN (RefS RefZ)
--
selN :: MonadSession m => Ref s xs -> m (Cap ctx (Sel xs)) (Cap ctx s) ()
-- | Select the first branch of a selection.
selN1 :: MonadSession m => m (Cap ctx (Sel (s : xs))) (Cap ctx s) ()
-- | Select the second branch of a selection.
selN2 :: MonadSession m => m (Cap ctx (Sel (s : (t : xs)))) (Cap ctx t) ()
-- | Select the third branch of a selection.
selN3 :: MonadSession m => m (Cap ctx (Sel (s : (t : (k : xs))))) (Cap ctx k) ()
-- | Select the fourth branch of a selection.
selN4 :: MonadSession m => m (Cap ctx (Sel (s : (t : (k : (r : xs)))))) (Cap ctx r) ()
-- | Type class for selecting a branch through injection.
--
-- Selects the first branch that matches the given session type.
--
--
-- prog :: MonadSession m => m ('Cap ctx (Sel '[Eps, String :!> Eps, Int :!> Eps])) ('Cap ctx Eps) ()
-- prog = sel >> send "c" >>= eps
--
--
-- It should be obvious that you cannot select a branch using sel
-- if that branch has the same session type as a previous branch.
class Select xs s
sel :: (Select xs s, MonadSession m) => m (Cap ctx (Sel xs)) (Cap ctx s) ()
-- | Infix synonym for offS
(<&) :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx (Off (t : xs))) r a -> m (Cap ctx (Off (s : (t : xs)))) r a
infixr 1 <&
-- | Infix synonym for offer
--
-- Using both <& and <&> we can now
-- construct an offering as follows:
--
-- -- branch1 -- <& branch2 -- <& branch3 -- <&> branch4 ---- -- This will be parsed as -- --
-- (branch1 -- <& (branch2 -- <& (branch3 -- <&> branch4))) --(<&>) :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx t) r a -> m (Cap ctx (Off '[s, t])) r a infix 2 <&> -- | Takes two session typed programs and constructs an offering consisting -- of two branches offer :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx t) r a -> m (Cap ctx (Off '[s, t])) r a -- | A fixpoint combinator for recursion -- -- The argument function must take a recursion variable as an argument -- that can be used to denote the point of recursion. -- -- For example: -- --
-- prog = recurseFix \f -> do -- send 5 -- f ---- -- This program will send the number 5 an infinite amount of times. recurseFix :: MonadSession m => (m (Cap (s : ctx) V) r a -> m (Cap (s : ctx) s) r a) -> m (Cap ctx (R s)) r a -- | Monadic composable definition of recurse recurse0 :: MonadSession m => m (Cap ctx (R s)) (Cap (s : ctx) s) () -- | Monadic composable definition of weaken weaken0 :: MonadSession m => m (Cap (t : ctx) (Wk s)) (Cap ctx s) () -- | Monadic composable definition of var var0 :: MonadSession m => m (Cap (s : ctx) V) (Cap (s : ctx) s) () -- | Monadic composable definition of eps eps0 :: MonadSession m => m (Cap ctx Eps) (Cap ctx Eps) () instance (tl ~ Control.SessionTypes.Types.TypeEqList xs s, Control.SessionTypes.MonadSession.Select' xs s tl) => Control.SessionTypes.MonadSession.Select xs s instance Control.SessionTypes.MonadSession.Select' (s : xs) s ('GHC.Types.True : tl) instance Control.SessionTypes.MonadSession.Select' (r : xs) t tl => Control.SessionTypes.MonadSession.Select' (s : r : xs) t ('GHC.Types.False : tl) -- | This module defines an interpreter for visualizing session types. -- -- Using visualize or visualizeP you can create a diagram -- that displays a session type using a set of nodes and arrows that -- connect these nodes. module Control.SessionTypes.Visualize -- | Visualizes the session type of a given STTerm You may use -- this function in the following way -- --
-- main = visualize st ---- -- Then the following command will generate a diagram named -- "sessiontype.png" -- --
-- stack exec vis-sessiontype -- -o sessiontype.png -w 400 ---- -- For more information on how to generate a diagram please visit the -- diagrams package visualize :: forall m ctx s r a. (MonadSession m, MkDiagram s) => m (Cap ctx s) r a -> IO () -- | Visualizes a given session type denoted by a Proxy. visualizeP :: forall s. MkDiagram s => Proxy s -> IO () -- | Type class for constructing a diagram that visualizes the session -- types class MkDiagram (s :: ST k) where mkDiagram p = do { dstate <- dstateWNodesIO; (diag, DState n _ _ d g) <- runStateT connectGrid dstate; fmap fst $ runStateT connectRecursions (DState n 0 (0, 0) diag g) } where dstateWNodesIO = fmap snd $ runStateT (placeNodes p) (newDState $ newGrid (getX p) (getY p)) instance GHC.Show.Show Control.SessionTypes.Visualize.NodeType instance GHC.Classes.Eq Control.SessionTypes.Visualize.NodeType instance forall k (s :: Control.SessionTypes.Types.ST k). (Control.SessionTypes.Visualize.Coordinates s, Control.SessionTypes.Visualize.PlaceNodes s) => Control.SessionTypes.Visualize.MkDiagram s instance forall k (r :: Control.SessionTypes.Types.ST k) (a :: k). Control.SessionTypes.Visualize.Coordinates r => Control.SessionTypes.Visualize.Coordinates (a 'Control.SessionTypes.Types.:!> r) instance forall k (r :: Control.SessionTypes.Types.ST k) (a :: k). Control.SessionTypes.Visualize.Coordinates r => Control.SessionTypes.Visualize.Coordinates (a 'Control.SessionTypes.Types.:?> r) instance forall k (t :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.Coordinates t => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Sel '[t]) instance forall k (s :: Control.SessionTypes.Types.ST k) (t :: Control.SessionTypes.Types.ST k) (xs :: [Control.SessionTypes.Types.ST k]). (Control.SessionTypes.Visualize.Coordinates s, Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Sel (t : xs))) => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Sel (s : t : xs)) instance forall k (t :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.Coordinates t => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Off '[t]) instance forall k (s :: Control.SessionTypes.Types.ST k) (t :: Control.SessionTypes.Types.ST k) (xs :: [Control.SessionTypes.Types.ST k]). (Control.SessionTypes.Visualize.Coordinates s, Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Off (t : xs))) => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Off (s : t : xs)) instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.Coordinates s => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.R s) instance Control.SessionTypes.Visualize.Coordinates 'Control.SessionTypes.Types.V instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.Coordinates s => Control.SessionTypes.Visualize.Coordinates ('Control.SessionTypes.Types.Wk s) instance Control.SessionTypes.Visualize.Coordinates 'Control.SessionTypes.Types.Eps instance forall k (a :: k) (r :: Control.SessionTypes.Types.ST k). (Data.Typeable.Internal.Typeable a, Control.SessionTypes.Visualize.PlaceNodes r) => Control.SessionTypes.Visualize.PlaceNodes (a 'Control.SessionTypes.Types.:!> r) instance forall k (a :: k) (r :: Control.SessionTypes.Types.ST k). (Data.Typeable.Internal.Typeable a, Control.SessionTypes.Visualize.PlaceNodes r) => Control.SessionTypes.Visualize.PlaceNodes (a 'Control.SessionTypes.Types.:?> r) instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.PlaceNodes s => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Sel '[s]) instance forall k (s :: Control.SessionTypes.Types.ST k) (t :: Control.SessionTypes.Types.ST k) (xs :: [Control.SessionTypes.Types.ST k]). (Control.SessionTypes.Visualize.Coordinates s, Control.SessionTypes.Visualize.PlaceNodes s, Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Sel (t : xs))) => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Sel (s : t : xs)) instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.PlaceNodes s => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Off '[s]) instance forall k (s :: Control.SessionTypes.Types.ST k) (t :: Control.SessionTypes.Types.ST k) (xs :: [Control.SessionTypes.Types.ST k]). (Control.SessionTypes.Visualize.Coordinates s, Control.SessionTypes.Visualize.PlaceNodes s, Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Off (t : xs))) => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Off (s : t : xs)) instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.PlaceNodes s => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.R s) instance Control.SessionTypes.Visualize.PlaceNodes 'Control.SessionTypes.Types.V instance forall k (s :: Control.SessionTypes.Types.ST k). Control.SessionTypes.Visualize.PlaceNodes s => Control.SessionTypes.Visualize.PlaceNodes ('Control.SessionTypes.Types.Wk s) instance Control.SessionTypes.Visualize.PlaceNodes 'Control.SessionTypes.Types.Eps -- | This module defines a GADT STTerm that is the very core of this -- library -- -- Session typed programs are constructed by composing the constructors -- of STTerm. -- -- Each constructor is annotated with a specific session type (except for -- Ret and Lift). -- -- By passing a constructor to another constructor as an argument their -- session types are joined to form a larger session type. -- -- We do not recommend explicitly composing the STTerm -- constructors. Instead make use of the functions defined in the -- Control.SessionTypes.MonadSession module. -- -- Of course a STTerm program in itself is not very useful as it -- is devoid of any semantics. However, an interpreter function can give -- meaning to a STTerm program. -- -- We define a couple in this library: Control.SessionTypes.Debug, -- Control.SessionTypes.Interactive, -- Control.SessionTypes.Normalize and -- Control.SessionTypes.Visualize. module Control.SessionTypes.STTerm -- | The STTerm GADT -- -- Although we say that a STTerm is annotated with a session type, -- it is actually annotated with a capability (Cap). -- -- The capability contains a context that is necessary for recursion and -- the session type. -- -- The constructors can be split in four different categories: -- --
-- prog = do -- send 5 -- x <- recv -- offer (eps x) (eps "") -- -- main = interactive prog ---- --
-- > Enter value of type String: "test" -- > (L)eft or (R)ight: L -- "test" --interactive :: (MonadIO m, HasConstraints '[Read, Show, Typeable] s, Show a) => STTerm m s r a -> m a -- | Different from interactive is that this function gives the user -- the choice to abort the session after each session typed action. -- -- Furthermore, it also prints additional output describing which session -- typed action occurred. interactiveStep :: (MonadIO m, HasConstraints '[Read, Show, Typeable] s, Show a) => STTerm m s r a -> m (Maybe a) -- | This module provides a type class for normalizing session typed -- programs. -- -- With normalizing we mean that we apply rewrites to a session typed -- program until we can no longer do so and that do not change the -- semantics of the program. -- -- The motivation for this module is that for two session typed programs -- to run a session they must be dual. Sometimes, one of these programs -- might not have a session type that is dual to the session type of the -- other program, -- -- but we can rewrite the program and therefore also the session type -- such that it is. It is of course important that we do not alter the -- semantics of the program when rewriting it. For that reason, any -- rewrite that we may apply must be isomorphic. -- -- A rewrite is isomorphic if we have two programs p and p', we can do a -- rewrite from p to p' and from p' to p. -- -- For now two types of rewrites are applied: Elimination of recursive -- types and flattening of branches. module Control.SessionTypes.Normalize -- | Type class for rewriting an STTerm to its normal form -- -- The type class has a single instance that is constrained with two type -- classes. One for each type of rewrite. class Normalize s s'' | s -> s'' normalize :: (Normalize s s'', Monad m) => STTerm m s (Cap '[] Eps) a -> STTerm m s'' (Cap '[] Eps) a -- | Type class for flattening branches -- -- The function flatten takes and traverses a STTerm. If it -- finds a branching session type that has a branch starting with another -- branching of the same type, then it will extract the branches of the -- inner branching and inserts these into the outer branching. This is -- similar to flattening a list of lists to a larger list. -- -- For example: -- --
-- Sel '[a,b, Sel '[c,d], e] ---- -- becomes -- --
-- Sel '[a,b,c,d,e] ---- -- This only works if the inner branching has the same type as the outer -- branch (Sel in Sel or Off in Off). -- -- Also, for now this rewrite only works if one of the branching of the -- outer branch starts with a new branching. -- -- For example: -- --
-- Sel '[a,b, Int :!> Sel '[c,d],e] ---- -- does not become -- --
-- Sel '[a,b,Int :!> c, Int :!> d, e] ---- -- This is something that will be added in the future. class Flatten s s' | s -> s' flatten :: (Flatten s s', Monad m) => STTerm m s r a -> STTerm m s' r a -- | Type class for eliminating unused recursive types. -- -- The function elimRec traverses a given STTerm. While -- doing so, it will attempt to remove constructors annotated with -- R or Wk from the program if in doing so does not change -- the behavior of the program. -- -- For example, in the following session type we may remove the inner -- R and the Wk. -- --
-- R (R (Wk V)) ---- -- We have that the outer R matches the recursion variable because -- of the use of Wk. -- -- That means the inner R does not match any recursion variable -- (the R is unused) and therefore may it and its corresponding -- constructor be removed from the STTerm program. -- -- We also remove the Wk, because the session type pushed into the -- context by the inner R has also been removed. -- -- The generated session type is -- --
-- R V --class ElimRec s s' | s -> s' elimRec :: (ElimRec s s', Monad m) => STTerm m s r a -> STTerm m s' r a instance forall a (s :: Control.SessionTypes.Types.Cap a) (s' :: Control.SessionTypes.Types.Cap a) (s'' :: Control.SessionTypes.Types.Cap a). (Control.SessionTypes.Normalize.Flatten s s', Control.SessionTypes.Normalize.ElimRec s' s'') => Control.SessionTypes.Normalize.Normalize s s'' instance forall a (el :: Control.SessionTypes.Types.Cap GHC.Types.Bool) (s :: Control.SessionTypes.Types.Cap a) (s' :: Control.SessionTypes.Types.Cap a). (el ~ Control.SessionTypes.Normalize.ElimRecAllPath s, Control.SessionTypes.Normalize.ElimRec' s s' el) => Control.SessionTypes.Normalize.ElimRec s s' instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (r :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (r' :: Control.SessionTypes.Types.ST a) (rml :: Control.SessionTypes.Types.Cap GHC.Types.Bool) (a1 :: a). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx r) ('Control.SessionTypes.Types.Cap ctx' r') rml => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx (a1 'Control.SessionTypes.Types.:!> r)) ('Control.SessionTypes.Types.Cap ctx' (a1 'Control.SessionTypes.Types.:!> r')) rml instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (r :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (r' :: Control.SessionTypes.Types.ST a) (rml :: Control.SessionTypes.Types.Cap GHC.Types.Bool) (a1 :: a). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx r) ('Control.SessionTypes.Types.Cap ctx' r') rml => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx (a1 'Control.SessionTypes.Types.:?> r)) ('Control.SessionTypes.Types.Cap ctx' (a1 'Control.SessionTypes.Types.:?> r')) rml instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rm :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rm) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel '[s'])) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Sel '[rm])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rm :: Control.SessionTypes.Types.ST GHC.Types.Bool) (t :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (t' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rmxs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rm), Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel (t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (t' : xs'))) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Sel rmxs))) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel (s : t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (s' : t' : xs'))) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Sel (rm : rmxs))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rm :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rm) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off '[s'])) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Off '[rm])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rm :: Control.SessionTypes.Types.ST GHC.Types.Bool) (t :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (t' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rmxs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rm), Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off (t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (t' : xs'))) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Off rmxs))) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off (s : t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (s' : t' : xs'))) ('Control.SessionTypes.Types.Cap rmctx ('Control.SessionTypes.Types.Off (rm : rmxs))) instance forall a (s :: Control.SessionTypes.Types.ST a) (ctx :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (rml :: Control.SessionTypes.Types.ST GHC.Types.Bool) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (s : ctx) s) ('Control.SessionTypes.Types.Cap (s' : ctx') s') ('Control.SessionTypes.Types.Cap (rml : rmctx) rml) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.R s)) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.R s')) ('Control.SessionTypes.Types.Cap rmctx ('GHC.Types.True 'Control.SessionTypes.Types.:!> rml)) instance forall a (s :: Control.SessionTypes.Types.ST a) (ctx :: [Control.SessionTypes.Types.ST a]) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rml :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (s : ctx) s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rml) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.R s)) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx ('GHC.Types.False 'Control.SessionTypes.Types.:!> rml)) instance forall a (t :: Control.SessionTypes.Types.ST a) (rm' :: Control.SessionTypes.Types.ST GHC.Types.Bool) (t' :: Control.SessionTypes.Types.ST a) (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rml :: Control.SessionTypes.Types.ST GHC.Types.Bool). (Control.SessionTypes.Normalize.ApplyElimRecPath t rm' ~ t', Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rml)) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (t : ctx) ('Control.SessionTypes.Types.Wk s)) ('Control.SessionTypes.Types.Cap (t' : ctx') ('Control.SessionTypes.Types.Wk s')) ('Control.SessionTypes.Types.Cap (rm' : rmctx) ('GHC.Types.True 'Control.SessionTypes.Types.:!> rml)) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rml :: Control.SessionTypes.Types.ST GHC.Types.Bool) (t :: Control.SessionTypes.Types.ST a). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx rml) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (t : ctx) ('Control.SessionTypes.Types.Wk s)) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap rmctx ('GHC.Types.False 'Control.SessionTypes.Types.:!> rml)) instance forall a (s :: Control.SessionTypes.Types.ST a) (ctx :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (rm :: Control.SessionTypes.Types.ST GHC.Types.Bool) (rmctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (s : ctx) s) ('Control.SessionTypes.Types.Cap (s' : ctx') s') ('Control.SessionTypes.Types.Cap (rm : rmctx) rm) => Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap (s : ctx) 'Control.SessionTypes.Types.V) ('Control.SessionTypes.Types.Cap (s' : ctx') 'Control.SessionTypes.Types.V) ('Control.SessionTypes.Types.Cap (rm : rmctx) 'Control.SessionTypes.Types.V) instance Control.SessionTypes.Normalize.ElimRec' ('Control.SessionTypes.Types.Cap '[] 'Control.SessionTypes.Types.Eps) ('Control.SessionTypes.Types.Cap '[] 'Control.SessionTypes.Types.Eps) ('Control.SessionTypes.Types.Cap '[] 'Control.SessionTypes.Types.Eps) instance forall a (rwl :: Control.SessionTypes.Types.Cap GHC.Types.Bool) (s :: Control.SessionTypes.Types.Cap a) (s' :: Control.SessionTypes.Types.Cap a). (rwl ~ Control.SessionTypes.Normalize.ListRewrites s, Control.SessionTypes.Normalize.Flatten' s s' rwl) => Control.SessionTypes.Normalize.Flatten s s' instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (ys :: [Control.SessionTypes.Types.ST a]) (ctx' :: [Control.SessionTypes.Types.ST a]) (ys' :: [Control.SessionTypes.Types.ST a]) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel ys)) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel ys')) ('Control.SessionTypes.Types.Cap nctx rwl) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel '['Control.SessionTypes.Types.Sel ys])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel ys')) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel '['GHC.Types.True 'Control.SessionTypes.Types.:!> rwl])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (y :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (y' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rw_y :: Control.SessionTypes.Types.ST GHC.Types.Bool) (x :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (x' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rw_xs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel '[y])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel '[y'])) ('Control.SessionTypes.Types.Cap nctx rw_y), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel (x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (x' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel rw_xs))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel ('Control.SessionTypes.Types.Sel '[y] : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (y' : x' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel ('GHC.Types.True 'Control.SessionTypes.Types.:!> rw_y : rw_xs))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rw_s :: Control.SessionTypes.Types.ST GHC.Types.Bool) (z :: Control.SessionTypes.Types.ST a) (ys :: [Control.SessionTypes.Types.ST a]) (x :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (z' :: Control.SessionTypes.Types.ST a) (xss :: [Control.SessionTypes.Types.ST a]) (rw_ys :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rw_xss :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel '[s'])) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel '[rw_s])), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel ('Control.SessionTypes.Types.Sel (z : ys) : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (z' : xss))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel ('GHC.Types.True 'Control.SessionTypes.Types.:!> 'Control.SessionTypes.Types.Sel rw_ys : rw_xss)))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel ('Control.SessionTypes.Types.Sel (s : z : ys) : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (s' : z' : xss))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel ('GHC.Types.True 'Control.SessionTypes.Types.:!> 'Control.SessionTypes.Types.Sel (rw_s : rw_ys) : rw_xss))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (ys :: [Control.SessionTypes.Types.ST a]) (ctx' :: [Control.SessionTypes.Types.ST a]) (ys' :: [Control.SessionTypes.Types.ST a]) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off ys)) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off ys')) ('Control.SessionTypes.Types.Cap nctx rwl) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off '['Control.SessionTypes.Types.Off ys])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off ys')) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off '['GHC.Types.True 'Control.SessionTypes.Types.:!> rwl])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl_s :: Control.SessionTypes.Types.ST GHC.Types.Bool) (x :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (x' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rwl_xs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off '[s'])) ('Control.SessionTypes.Types.Cap nctx rwl_s), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off (x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (x' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off rwl_xs))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off ('Control.SessionTypes.Types.Off '[s] : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (s' : x' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off ('GHC.Types.True 'Control.SessionTypes.Types.:!> rwl_s : rwl_xs))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl_s :: Control.SessionTypes.Types.ST GHC.Types.Bool) (z :: Control.SessionTypes.Types.ST a) (ys :: [Control.SessionTypes.Types.ST a]) (x :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (z' :: Control.SessionTypes.Types.ST a) (xss :: [Control.SessionTypes.Types.ST a]) (rwl_ys :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rw_xs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off '[s'])) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off '[rwl_s])), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off ('Control.SessionTypes.Types.Off (z : ys) : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (z' : xss))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off ('GHC.Types.True 'Control.SessionTypes.Types.:!> 'Control.SessionTypes.Types.Off rwl_ys : rw_xs)))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off ('Control.SessionTypes.Types.Off (s : z : ys) : x : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (s' : z' : xss))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off ('GHC.Types.True 'Control.SessionTypes.Types.:!> 'Control.SessionTypes.Types.Off (rwl_s : rwl_ys) : rw_xs))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap nctx rwl) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel '[s'])) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel '['GHC.Types.False 'Control.SessionTypes.Types.:!> rwl])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rw_s :: Control.SessionTypes.Types.ST GHC.Types.Bool) (r :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (r' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rw_xs :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap nctx rw_s), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel (r : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (r' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel rw_xs))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Sel (s : r : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Sel (s' : r' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Sel ('GHC.Types.False 'Control.SessionTypes.Types.:!> rw_s : rw_xs))) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl :: Control.SessionTypes.Types.ST GHC.Types.Bool). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap nctx rwl) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off '[s])) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off '[s'])) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off '['GHC.Types.False 'Control.SessionTypes.Types.:!> rwl])) instance forall a (ctx :: [Control.SessionTypes.Types.ST a]) (s :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (s' :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST GHC.Types.Bool]) (rwl_s :: Control.SessionTypes.Types.ST GHC.Types.Bool) (t :: Control.SessionTypes.Types.ST a) (xs :: [Control.SessionTypes.Types.ST a]) (t' :: Control.SessionTypes.Types.ST a) (xs' :: [Control.SessionTypes.Types.ST a]) (rwl_r :: [Control.SessionTypes.Types.ST GHC.Types.Bool]). (Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap nctx rwl_s), Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off (t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (t' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off rwl_r))) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.Off (s : t : xs))) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.Off (s' : t' : xs'))) ('Control.SessionTypes.Types.Cap nctx ('Control.SessionTypes.Types.Off ('GHC.Types.False 'Control.SessionTypes.Types.:!> rwl_s : rwl_r))) instance forall k a (ctx :: [Control.SessionTypes.Types.ST a]) (r :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (r' :: Control.SessionTypes.Types.ST a) (rwl :: k) (a1 :: a). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx r) ('Control.SessionTypes.Types.Cap ctx' r') rwl => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx (a1 'Control.SessionTypes.Types.:!> r)) ('Control.SessionTypes.Types.Cap ctx' (a1 'Control.SessionTypes.Types.:!> r')) rwl instance forall k a (ctx :: [Control.SessionTypes.Types.ST a]) (r :: Control.SessionTypes.Types.ST a) (ctx' :: [Control.SessionTypes.Types.ST a]) (r' :: Control.SessionTypes.Types.ST a) (rwl :: k) (a1 :: a). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx r) ('Control.SessionTypes.Types.Cap ctx' r') rwl => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx (a1 'Control.SessionTypes.Types.:?> r)) ('Control.SessionTypes.Types.Cap ctx' (a1 'Control.SessionTypes.Types.:?> r')) rwl instance forall a a1 (s :: Control.SessionTypes.Types.ST a1) (ctx :: [Control.SessionTypes.Types.ST a1]) (s' :: Control.SessionTypes.Types.ST a1) (ctx' :: [Control.SessionTypes.Types.ST a1]) (norm :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST a]). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap (s : ctx) s) ('Control.SessionTypes.Types.Cap (s' : ctx') s') ('Control.SessionTypes.Types.Cap (norm : nctx) norm) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx ('Control.SessionTypes.Types.R s)) ('Control.SessionTypes.Types.Cap ctx' ('Control.SessionTypes.Types.R s')) ('Control.SessionTypes.Types.Cap nctx norm) instance forall a a1 (t :: Control.SessionTypes.Types.ST a1) (t' :: Control.SessionTypes.Types.ST a1) (ctx :: [Control.SessionTypes.Types.ST a1]) (s :: Control.SessionTypes.Types.ST a1) (ctx' :: [Control.SessionTypes.Types.ST a1]) (s' :: Control.SessionTypes.Types.ST a1) (nctx :: [Control.SessionTypes.Types.ST a]) (norm :: Control.SessionTypes.Types.ST a) (k :: Control.SessionTypes.Types.ST a). (Control.SessionTypes.Normalize.RewriteTypes t ~ t', Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx s) ('Control.SessionTypes.Types.Cap ctx' s') ('Control.SessionTypes.Types.Cap nctx norm)) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap (t : ctx) ('Control.SessionTypes.Types.Wk s)) ('Control.SessionTypes.Types.Cap (t' : ctx') ('Control.SessionTypes.Types.Wk s')) ('Control.SessionTypes.Types.Cap (k : nctx) norm) instance forall a a1 (s :: Control.SessionTypes.Types.ST a1) (ctx :: [Control.SessionTypes.Types.ST a1]) (s' :: Control.SessionTypes.Types.ST a1) (ctx' :: [Control.SessionTypes.Types.ST a1]) (norm :: Control.SessionTypes.Types.ST a) (nctx :: [Control.SessionTypes.Types.ST a]). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap (s : ctx) s) ('Control.SessionTypes.Types.Cap (s' : ctx') s') ('Control.SessionTypes.Types.Cap (norm : nctx) norm) => Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap (s : ctx) 'Control.SessionTypes.Types.V) ('Control.SessionTypes.Types.Cap (s' : ctx') 'Control.SessionTypes.Types.V) ('Control.SessionTypes.Types.Cap (norm : nctx) 'Control.SessionTypes.Types.V) instance forall a a1 (ctx :: [Control.SessionTypes.Types.ST a1]) (nctx :: [Control.SessionTypes.Types.ST a]). Control.SessionTypes.Normalize.Flatten' ('Control.SessionTypes.Types.Cap ctx 'Control.SessionTypes.Types.Eps) ('Control.SessionTypes.Types.Cap ctx 'Control.SessionTypes.Types.Eps) ('Control.SessionTypes.Types.Cap nctx 'Control.SessionTypes.Types.Eps) -- | This module defines a new type for constructing more efficient -- STTerm programs. module Control.SessionTypes.Codensity -- | We define an indexed codensity monad that allows us to reduce -- quadratic complexity from repeated use of (>>=) in a session -- typed program to linear complexity. newtype IxC m s r a IxC :: (forall b k. (a -> STTerm m r k b) -> STTerm m s k b) -> IxC m s r a [runIxC] :: IxC m s r a -> forall b k. (a -> STTerm m r k b) -> STTerm m s k b -- | Turns the IxC representation of a program to the STTerm -- representation. -- -- The idea is to apply abs on a IxC program to make the -- resulting STTerm program more efficient. abs :: Monad m => IxC m s r a -> STTerm m s r a -- | Transforms an STTerm program into a IxC representation. -- -- Note that applying this function to a session typed program and then -- applying abs to the result will not be more efficient. -- -- This is because applying rep already induces quadratic -- complexity. rep :: Monad m => STTerm m s r a -> IxC m s r a instance Control.SessionTypes.Indexed.IxFunctor (Control.SessionTypes.Codensity.IxC m) instance Control.SessionTypes.Indexed.IxApplicative (Control.SessionTypes.Codensity.IxC m) instance Control.SessionTypes.Indexed.IxMonad (Control.SessionTypes.Codensity.IxC m) instance GHC.Base.Monad m => Control.SessionTypes.MonadSession.MonadSession (Control.SessionTypes.Codensity.IxC m) -- | This packages provides a deep embedded domain-specific language for -- writing session typed program. -- -- A session typed program is a program annotated with session types. A -- session type describes a communication protocol at the type-level. -- -- The motivation for doing so is that it gives you a static guarantee -- that a program correctly implements a protocol. It may even guarantee -- that no deadlocking can occur. -- -- The following constitutes the most important parts of this library for -- writing session typed programs. -- --
-- prog :: MonadSession m => m ('Cap ctx (Sel '[a,b,c,d])) ('Cap ctx Eps) ()
--
-- MonadSession m => m ('Cap ctx b) ('Cap ctx Eps) ()
-- prog2 = prog >> selN (RefS RefZ)
--
selN :: MonadSession m => Ref s xs -> m (Cap ctx (Sel xs)) (Cap ctx s) ()
-- | Select the first branch of a selection.
selN1 :: MonadSession m => m (Cap ctx (Sel (s : xs))) (Cap ctx s) ()
-- | Select the second branch of a selection.
selN2 :: MonadSession m => m (Cap ctx (Sel (s : (t : xs)))) (Cap ctx t) ()
-- | Select the third branch of a selection.
selN3 :: MonadSession m => m (Cap ctx (Sel (s : (t : (k : xs))))) (Cap ctx k) ()
-- | Select the fourth branch of a selection.
selN4 :: MonadSession m => m (Cap ctx (Sel (s : (t : (k : (r : xs)))))) (Cap ctx r) ()
-- | Type class for selecting a branch through injection.
--
-- Selects the first branch that matches the given session type.
--
--
-- prog :: MonadSession m => m ('Cap ctx (Sel '[Eps, String :!> Eps, Int :!> Eps])) ('Cap ctx Eps) ()
-- prog = sel >> send "c" >>= eps
--
--
-- It should be obvious that you cannot select a branch using sel
-- if that branch has the same session type as a previous branch.
class Select xs s
sel :: (Select xs s, MonadSession m) => m (Cap ctx (Sel xs)) (Cap ctx s) ()
-- | Infix synonym for offS
(<&) :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx (Off (t : xs))) r a -> m (Cap ctx (Off (s : (t : xs)))) r a
infixr 1 <&
-- | Infix synonym for offer
--
-- Using both <& and <&> we can now
-- construct an offering as follows:
--
-- -- branch1 -- <& branch2 -- <& branch3 -- <&> branch4 ---- -- This will be parsed as -- --
-- (branch1 -- <& (branch2 -- <& (branch3 -- <&> branch4))) --(<&>) :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx t) r a -> m (Cap ctx (Off '[s, t])) r a infix 2 <&> -- | Takes two session typed programs and constructs an offering consisting -- of two branches offer :: MonadSession m => m (Cap ctx s) r a -> m (Cap ctx t) r a -> m (Cap ctx (Off '[s, t])) r a -- | A fixpoint combinator for recursion -- -- The argument function must take a recursion variable as an argument -- that can be used to denote the point of recursion. -- -- For example: -- --
-- prog = recurseFix \f -> do -- send 5 -- f ---- -- This program will send the number 5 an infinite amount of times. recurseFix :: MonadSession m => (m (Cap (s : ctx) V) r a -> m (Cap (s : ctx) s) r a) -> m (Cap ctx (R s)) r a -- | Monadic composable definition of recurse recurse0 :: MonadSession m => m (Cap ctx (R s)) (Cap (s : ctx) s) () -- | Monadic composable definition of weaken weaken0 :: MonadSession m => m (Cap (t : ctx) (Wk s)) (Cap ctx s) () -- | Monadic composable definition of var var0 :: MonadSession m => m (Cap (s : ctx) V) (Cap (s : ctx) s) () -- | Monadic composable definition of eps eps0 :: MonadSession m => m (Cap ctx Eps) (Cap ctx Eps) () -- | The session type data type -- -- Each constructor denotes a specific session type. Using the -- DataKinds pragma the constructors are promoted to types and -- ST is promoted to a kind. data ST a -- | Send a value (:?>) :: a -> (ST a) -> ST a -- | Recv a value (:!>) :: a -> (ST a) -> ST a -- | Selection of branches Sel :: [ST a] -> ST a -- | Offering of branches Off :: [ST a] -> ST a -- | Delimit the scope of recursion R :: (ST a) -> ST a -- | Weaken the scope of recursion Wk :: (ST a) -> ST a -- | Recursion variable V :: ST a -- | End of the session Eps :: ST a -- | A capability that stores a context/scope that is a list of session -- types and a session type data Cap a Cap :: [ST a] -> (ST a) -> Cap a -- | Retrieves the session type from the capability -- | Retrieves the context from the capability -- | Type family for calculating the dual of a session type. It may be -- applied to a capability. -- -- We made Dual injective to support calculating the dual of a -- selection that contains an ambiguous branch. Of course that does -- require that the dual of that ambiguous branch must be known. -- | Type family for calculating the dual of a session type. It may be -- applied to the actual session type. -- | Type family for calculating the dual of a list of session types. -- | Type family for removing the send session type from the given session -- type. It may be applied to a capability. -- | Type family for removing the send session type from the given session -- type. It may be applied to a session type. -- | Type family for removing the send session type from a list of session -- types. -- | Type family for removing the receive session type from the given -- session type. It may be applied to a capability. -- | Type family for removing the receive session type from a list of -- session types. -- | Type family for removing the receive session type from the given -- session type. It may be applied to a session type. -- | Type family for applying a constraint to types of kind Type in -- a session type. It may be applied to a capability. -- | Type family for applying a constraint to types of kind Type in -- a list of session types. -- | Type family for applying a constraint to types of kind Type in -- a session type. It may be applied to a session type. -- | Type family for applying zero or more constraints to types of kind -- Type in a list of session types. It may be applied to a -- capability. -- | Promoted ifThenElse -- | Promoted not -- | Promoted || -- | Data type that takes a kind as an argument. Its sole constructor takes -- two capabilities parameterized by the kind argument. -- -- This data type is useful if it is necessary for an indexed monad to be -- indexed by four parameters. data Prod t (:*:) :: (Cap t) -> (Cap t) -> Prod t -- | Type family for returning the first argument of a product. -- | Type family for returning the second argument of a product. -- | Data type defining natural numbers data Nat Z :: Nat S :: Nat -> Nat -- | Data type that can give us proof of membership of an element in a list -- of elements. data Ref s xs [RefZ] :: Ref s (s : xs) [RefS] :: Ref s (k : xs) -> Ref s (t : (k : xs)) -- | Type family for computing which types in a list of types are equal to -- a given type. -- | Promoted ++ -- | This module describes an interpreter for purely evaluating session -- typed programs -- -- that is based on the paper Beauty in the beast by Swierstra, -- W., & Altenkirch, T. -- -- Impurity in a session typed programs mainly comes from three things: -- receives, branching and lifting. -- -- Using the session type we can easily determine the type of the message -- that each receive should expect. -- -- This information allows us to define a stream of values of different -- types that provides input for each receive. -- -- In the sessiontyped-distributed library we send and receive booleans -- to enable branching. -- -- It is also possible to provide some kind of input that makes this -- choice. -- -- The current structure of the Lift constructor does not allow us -- to purely evaluate a Lift. -- -- As such a session typed program may not contain a lift for it to be -- purely evaluated. See runM as an alternative. module Control.SessionTypes.Debug -- | Purely evaluates a given STTerm using the input defined by -- Stream. -- -- The output is described in terms of the session type actions within -- the given program -- -- An example of how to use this function goes as follows: -- --
-- prog :: STTerm Identity ('Cap '[] (Int :!> String :?> Eps)) ('Cap '[] Eps) String
-- prog = send 5 >> recv >>= eps
--
-- strm = S_Send $ S_Recv "foo" S_Eps
--
--
-- -- >>> run prog strm -- O_Send 5 $ O_Recv "foo" $ O_Eps "foo" --run :: HasConstraint Show s => STTerm m s (Cap ctx Eps) a -> Stream s -> Output s a -- | Instead of describing the session typed actions, it returns a list of -- the results of all branches of all offerings. -- --
-- prog = offer (eps 10) (eps 5) -- strm = S_OffS S_Eps S_Eps ---- --
-- >>> runAll prog strm -- [10,5] --runAll :: HasConstraint Show s => STTerm m s (Cap ctx Eps) a -> Stream s -> [a] -- | Same as runAll but applies head to the resulting list -- --
-- >>> runSingle prog strm -- 10 --runSingle :: HasConstraint Show s => STTerm m s (Cap ctx Eps) a -> Stream s -> a -- | run cannot deal with lifted computations. This makes it limited -- to session typed programs without any use of lift. -- -- This function allows us to evaluate lifted computations, but as a -- consequence is no longer entirely pure. runM :: (Monad m, HasConstraint Show s) => STTerm m s (Cap ctx Eps) a -> Stream s -> m (Output s a) -- | Monadic version of runAll. runAllM :: (Monad m, HasConstraint Show s) => STTerm m s (Cap ctx Eps) a -> Stream s -> m [a] -- | Monad version of runSingle runSingleM :: (Monad m, HasConstraint Show s) => STTerm m s (Cap ctx Eps) a -> Stream s -> m a -- | We use the Stream data type to supply input for the receives in -- a session typed programs. -- -- We annotate a Stream with a capability for the following three -- reasons: -- --