예제 #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))));
 }
예제 #2
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)))))));
            }
        }