namespace SessionTypes { public class Eps { } public class Send { } public class Recv { } public class Choose { } public class Follow { } public class Dual { private Dual() { } public static Dual eps = new Dual(); public Dual, Recv> send() { return new Dual, Recv>(); } public Dual, Send> recv() { return new Dual, Send>(); } public Dual, Follow> choose(Dual right) { return new Dual, Follow>(); } public Dual, Choose> follow(Dual right) { return new Dual, Choose>(); } public Dual flip() { return new Dual(); } public void confirm() { } } public class Session { private delegate R Thunk(); private Thunk action; private Session() { } private Session(Thunk thunk) { action = thunk; } public delegate Y Func(X x); public Session(A a) { action = () => a; } public Session bind(Func> next) { return new Session(() => { return next(this.action()).action(); }); } public static C run(Dual witness, Session r, Session s) { witness.confirm(); return s.action(); } } }