]O+      !"#$%&'()* 6IxCont is a continuation monad that supports changing 8 of the answer type during the computation. The result  is a functor s x&, where the caller of the computation , controls the type held inside the functor. ;IxMonad (Indexed Monad) carries type-level state through a D computation. For an IxMonad m, m px py a represents a computation = with precondition px, postcondition py, and result value a.  px and py. can be thought of as type-level propositions 8 that hold at the beginning and end of the computation. ?mapCont changes the answer type of an IxCont, given a function ! that maps any (s x) to a (s y). +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~       # 1Loop is just nicely-named Either; it is used for = choosing whether or not to loop in these simplified looping  primitives. JBy indexing using a data family, we get an untagged representation of the 7 session; resolving how to link sessions together with connect can happen O at compile-time. A similar encoding is possible using GADTs, but it requires * runtime branching based on the GADT tag. IxCont s x y a == forall b. (a -> s y b) -> s x b; that is, if you give us ' a continuation function that takes an a& and outputs the rest of the session, J we can give you a representation of the full session. When a session is  complete, y is Eps5, the empty session, so getting the full session out  is just "runIxCont (getSession session) Eps$ which gives you the result of type  InSession session_type a SInSession s v is a functor type representing a session that results in the value v X being computed by the session. s should be indexed by one of the session types above, R although you can extended the session type system by adding additional instances % here and to Dual and Connect below. a :++: b is session a followed by session b. : This is mostly used for constructing looping constructs;  you generally won't need to use it yourself. a :* b is the session a zero or more times followed by b'. Either side may terminate the loop. a :!* b is the session a zero or more times followed by b#, choosing whether or not to loop. a :?* b is the session a zero or more times followed by b, offering the loop. a :|: b$ allows the choice between sessions a and b at runtime a :&: b offers both the sessions a and b to the other end a :!: r writes a followed by the sesison r a :?: r reads a followed by the session r Eps is the empty session. WM stands for  wrapped monad; it wraps any Prelude monad.  This doesn'1t really belong in this module, but exporting it ( correctly from IxMonad is a real pain. 7 This allows you to use NoImplicitPrelude when writing  main in the following way:   module Main where  import Control.Coroutine  main = runWM $ do  LiftWM $ putStrLn  hello world  You never need3 to explicitly call close; doing so just seals the  "rest-of-computation" parameter of the session. 2get reads an element from the connected coroutine !3put x sends the value x to the connected coroutine "3cat m takes a completed session and connects it at 5 the beginning of a sequence inside another session. #7offer s1 s2 gives the other side the choice of whether $ to continue with session s1 or s2. $*sel1 chooses the first branch of an offer %+sel2 chooses the second branch of an offer &loopC is the client side of a while loop; it takes the current E loop state, and a computation that figures out the next loop state, ) and loops until the computation returns Done. Initial loop state Session for the loop Result of the loop 'loopS is the server side of a while loop; it must always offer C the client the option to terminate the loop at each iteration, or  to continue the loop. Initial loop state Session for the loop Result of the loop (Cloop is a slightly more complicated looping primitive where either F side of the loop may choose to terminate the loop at each iteration. H It is useful for a server that has a fixed amount of data to give out, 2 when the client can also choose to escape early. Initial loop state Session for the loop Result of the loop )1runSession converts a session computation into a  connectable  session. *-connect two completed sessions to each other +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~       !"#$%&'()*" !"#$%  &'() *"    !"#$%&'()*      !"#$%&'()*+,-+./+,0123+45+46+47+89+:;+:<+,=+,>+?@+?A+BC+DE+DF+DG+DH+IJ+IK+?L+DM+DN+IO+PQ+BR+BS+,T+?U+IV+WX+BY+PZ+B[+\]1^_1`a1`b1`c1`defg1hi+Bj1`k+lm+,n1^o1^p+lq+lr+st+8u+8v+8w+8x+8y+8z+8{+8|+8}+8~+8+8+++++l++++++++++W+W+W+W+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+P+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+.++++++++++?+?+?+?+?+\+\+\+\+\+\+\+\+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4 +4 +4 +4 +4 +++++D+D+D+D+D+D+,+,+,+,+,+,+,+, +:!+:"+I#+I$+I%+I&+I'+I(+I)+I*+I++I,1h-1h.1h/0123456789:;Coroutine-0.1.0.0Control.Monad.IndexedControl.CoroutineIxCont runIxContIxMonadreturn>>=>>failmapContConnectconnectDualLoopDoneSession getSession InSession:++::*:!*:?*:|::&::!::?:EpsWMLiftWMrunWMclosegetputcatoffersel1sel2loopCloopSloop runSessionconnectsbaseGHC.Base++GHC.Errerrorfoldrghc-primGHC.PrimseqGHC.Listconcatfilterzip System.IOprint Data.Tuplefstsnd otherwisemapGHC.Num fromInteger-GHC.Real fromRationalGHC.EnumenumFrom enumFromThen enumFromToenumFromThenTo GHC.Classes==>=negateBoundedEnumEq GHC.FloatFloating FractionalIntegralFunctorNumOrdGHC.ReadReadReal RealFloatRealFracGHC.ShowShowGHC.BoolBool GHC.TypesCharDoubleFloatInt integer-gmpGHC.Integer.TypeInteger GHC.OrderingOrderingRationalIO Data.EitherEitherStringFalseTrueLeftRightPrelude$!readIOreadLn appendFile writeFilereadFileinteract getContentsgetLinegetCharputStrLnputStrputCharSystem.IO.ErrorcatchGHC.IO.ExceptionioError Text.Readreadreadseither Data.Listunwordswordsunlineslinesproductsumfoldl1minimummaximumlex readParenreadList readsPrecacoshatanhasinhcoshtanhsinhacosatanasincostansinlogBase**logsqrtexppiatan2isIEEEisNegativeZeroisDenormalized isInfiniteisNaN scaleFloat significandexponent encodeFloat decodeFloat floatRange floatDigits floatRadixlcmgcd^^^oddeven realToFrac fromIntegral toRational toIntegerdivModquotRemmoddivremquotrecip/floorceilingroundtruncateproperFraction undefinedText.ParserCombinators.ReadPReadSGHC.IOFilePathIOError userError Control.MonadmapM_mapM sequence_sequence=<<subtractsignumabs*+ showParen showStringshowCharshowsShowSshowListshow showsPrecunzip3unzipzipWith3zipWithzip3!! concatMaplookupnotElemelemallanyorandreversebreakspansplitAtdroptake dropWhile takeWhilecycle replicaterepeatiteratescanr1scanrfoldr1scanl1scanlfoldllengthnullinitlasttailhead Data.MaybemaybeNothingJustMaybemaxBoundminBoundfromEnumtoEnumpredsuccasTypeOfuntil$flip.constidfmapuncurrycurrynot||&&/=minmax<=><compareGTEQLT mapSessionGoStopStarSStarCCATCRCLOWR