Beispiel #1
0
 public static Process <T2> SelectMany <T1, T2>(this Process <T1> m, Func <T1, Process <T2> > f)
 {
     return(m.Match(
                halt: e => new Halt <T2>(e),
                emit: (h, t) => Try(() => f(h)).Concat(() => t.SelectMany(f)),
                await: (req, recv) => Await <T2> .Create(req, recv.AndThen(p => p.SelectMany(f))),
                cont: cw => new Cont <T2>(cw.Select(p => p.SelectMany(f))),
                eval: (effect, next) => new Eval <T2>(effect, next.SelectMany(f))));
 }
Beispiel #2
0
 public static Process <Unit> Delay(int milliseconds)
 {
     return(Await <Unit> .Create(() =>
     {
         Thread.Sleep(milliseconds);
         return Unit.Only;
     },
                                 either => either.Match(
                                     left: ex => new Halt <Unit>(ex),
                                     right: i => new Halt <Unit>(End.Only))));
 }
Beispiel #3
0
 private static Process <T> BufferHelper <TState, T>(TState buffer, Func <TState> @new, Action <T, TState> add,
                                                     Func <TState, bool> ready, Func <TState, T> flush)
 {
     return(Await <T> .Create(() => default(T), either => either.Match(
                                  left: e => new Halt <T>(e),
                                  right: i =>
     {
         add(i, buffer);
         return ready(buffer) ? new Emit <T>(flush(buffer)).Concat(() => BufferHelper(@new(), @new, add, ready, flush)) : new Cont <T>(() => BufferHelper(buffer, @new, add, ready, flush));
     })));
 }
Beispiel #4
0
        private static Process <IEither <T1, T2> > HandleBranch <T1, T2>(object l, Func <IEither <Exception, object>, Process <T1> > recvl, Func <IEither <Exception, object>, Process <T2> > recvr, bool isLeft)
        {
            Process <IEither <T1, T2> > retval;
            var pair = (Tuple <object, Func <object> >)l;

            if (isLeft)
            {
                retval = Wye(recvl(pair.Item1.AsRight <Exception, object>()), Await <T2> .Create(pair.Item2, recvr));
            }
            else
            {
                retval = Wye(Await <T1> .Create(pair.Item2, recvl), recvr(pair.Item1.AsRight <Exception, object>()));
            }
            return(retval);
        }
Beispiel #5
0
        public static Process <IEither <T1, T2> > Wye <T1, T2>(Process <T1> p1, Process <T2> p2)
        {
            var random = new Random();

            if (random.Next() % 2 == 0)
            {
                return(p1.Match(
                           halt: e => new Halt <IEither <T1, T2> >(e),
                           emit: (h, t) => new Emit <IEither <T1, T2> >(h.AsLeft <T1, T2>(), Wye(t, p2)),
                           cont: cw => new Cont <IEither <T1, T2> >(cw.Select(p => Wye(p, p2))),
                           eval: (effect, next) => new Eval <IEither <T1, T2> >(effect, Wye(next, p2)),
                           await: (reql, recvl) => p2.Match <Process <IEither <T1, T2> > >(
                               halt: e => new Halt <IEither <T1, T2> >(e),
                               emit: (h, t) => new Emit <IEither <T1, T2> >(h.AsRight <T1, T2>(), Wye(Await <T1> .Create(reql, recvl), t)),
                               cont: cw => new Cont <IEither <T1, T2> >(cw.Select(p => Wye(p1, p))),
                               eval: (effect, next) => new Eval <IEither <T1, T2> >(effect, Wye(p1, next)),
                               await: (reqr, recvr) => Await <IEither <T1, T2> > .Create(WhenEither(reql, reqr), x => x.Match(
                                                                                             left: e => new Halt <IEither <T1, T2> >(e),
                                                                                             right: either => either.Match(
                                                                                                 left: l => HandleBranch(l, recvl, recvr, true),
                                                                                                 right: r => HandleBranch(r, recvl, recvr, false)))))));
            }
            else
            {
                return(p2.Match(
                           halt: e => new Halt <IEither <T1, T2> >(e),
                           emit: (h, t) => new Emit <IEither <T1, T2> >(h.AsRight <T1, T2>(), Wye(p1, t)),
                           cont: cw => new Cont <IEither <T1, T2> >(cw.Select(p => Wye(p1, p))),
                           eval: (effect, next) => new Eval <IEither <T1, T2> >(effect, Wye(p1, next)),
                           await: (reqr, recvr) => p1.Match <Process <IEither <T1, T2> > >(
                               halt: e => new Halt <IEither <T1, T2> >(e),
                               emit: (h, t) => new Emit <IEither <T1, T2> >(h.AsLeft <T1, T2>(), Wye(t, p2)),
                               cont: cw => new Cont <IEither <T1, T2> >(cw.Select(p => Wye(p, p2))),
                               eval: (effect, next) => new Eval <IEither <T1, T2> >(effect, Wye(next, p2)),
                               await: (reql, recvl) => Await <IEither <T1, T2> > .Create(WhenEither(reql, reqr), x => x.Match(
                                                                                             left: e => new Halt <IEither <T1, T2> >(e),
                                                                                             right: either => either.Match(
                                                                                                 left: l => HandleBranch(l, recvl, recvr, true),
                                                                                                 right: r => HandleBranch(r, recvl, recvr, false)))))));
            }
        }
Beispiel #6
0
 public static Process <T> AwaitAndEmit <T>(Func <T> effect)
 {
     return(Await <T> .Create(effect, result => result.Match <Process <T> >(
                                  left: ex => new Halt <T>(ex),
                                  right: ti => new Emit <T>(ti))));
 }
Beispiel #7
0
 public static Process <T> While <T>(this Process <T> p, Func <bool> predicate)
 {
     return(Await <T> .Create(predicate, either => either.Match(
                                  left: e => new Halt <T>(e),
                                  right: b => b ? p.Concat(() => p.While(predicate)) : new Halt <T>(End.Only))));
 }