úÎ5K03      !"#$%&'()*+,-./012None3TChan| has three operations: 435643564356None789:;<7:;<789:;< Safe-InferredF(:?:)| are declared right associative and with higher precedence than  |(:+:)| and |(:&:)|.} EIf the process on one end of a channel speaks a particular protocol, G its correspondant at the other end of the channel must be prepared to L understand it. For example, if one process speaks |Int :!: Bool :?: Eps|, 4 the other process must implement the dual protocol F |Int :?: Bool :!: Eps|. We encode the duality relation using a type < class with multiple parameters and functional dependencies  c#itep{Jones1997Type,Jones2000Type}.  =>?@ABC   =>?@ABCNone@Session| is implemented as the composition of the IO monad with , a reader monad carrying a untyped channel. a :!: r| to |r|. + In its implementation, |unsafeWriteUChan| H indiscriminately transmits values of any type over an untyped channel. J Thus, if we fail to ensure that the receiving process expects a value of ) type |a|, things can go very wrong. In Sectionref{sec:theory}, we  argue that this cannot happen. HPredictably, |recv| requires the capability to receive an |a|, which it  then produces: @Session|, this does not jeopardize safety in the sense that any F messages received will still have the expected representation. Some I formulations of session types guarantee that a session, once initiated, C will run to completion, but this seems unrealistic for real-world F programs. Handling exceptions from within a session remains an open  problem. paragraph{Alternation.} GThe session actions |sel1|, |sel2|, and |offer| implement alternation. + Action |sel1| selects the left side of an ``internal choice'', D thereby replacing a session |r :+: s| with the session |r|; |sel2| O selects the right side. On the other side of the channel, |offer| combines a A |Session| computation for |r| with a computation for |s| into a ! computation that can handle |r :&(: s|. Dynamically, |sel1| sends |True| H over the channel, whereas |sel2| sends |False|, and |offer| dispatches  on the boolean value received. >Rec|, representing an environment that closes over |r|. Upon C encountering a variable occurence |Var |$n$, where $n$ is a Peano  numeral, we restore the F $n$th session type from the stack and return the stack to its former 3 state, using $n$ expressed with |zero| and |suc|: @request| receives a new, untyped channel from |accept| over the G |Rendezvous| channel and then runs the computation using the channel.  D EFGHIJKL,MNOPQRSTUVWXYZ[\    D  EFGHIJKLNone,Aswap| may be combined to exchange any two adjacent capabilities. ]^_` a!"#$%&'()*+,-./012bcde1MNOPQRSTUVWXYZ[\  !"#$%&'()*+,-./012)*!%"#$12&'(+,- ./0]^_` a!"#$%&'()*+,-./012bcdef      !"#$% !&'()*+,-./0123456789:;<=>?@ABCABDABEABFABGABHABIABJABKABLAMNAMOAMPAMQAMRAMS:"T=>?@Usimple-sessions-0.1.3-Control.Concurrent.SimpleSession.SessionTypes)Control.Concurrent.SimpleSession.Implicit+Control.Concurrent.SimpleSession.Positional&Control.Concurrent.SimpleSession.TChan&Control.Concurrent.SimpleSession.UChanVarRec:&::+:DualEps:?::!:SZ RendezvousPoppopCapSessionsendrecvcloseiosel1sel2offerenterzerosuc newRendezvousacceptrequestChanneldigswap forkSession runSessionsend_caprecv_capnewTChanTChan writeTChan readTChanUChanCCunUChannewUChanunsafeWriteUChanunsafeReadUChan $fDualVarVar $fDualRecRec $fDual:&::+: $fDual:+::&: $fDualEpsEps $fDual:?::!: $fDual:!::?: unSession $fPopCapCap $fPopCapCap0$fIxMonadSession$fIxApplicativeSession$fIxPointedSession$fIxFunctorSession indexed-0.1Control.Monad.Indexed iapIxMonad=<<<>>>=ijoinibindIxMonadimzero IxMonadZeroimplus IxMonadPlusData.Functor.Indexedimap IxFunctoriap IxApplicativeireturn IxPointed_cast