public IReservationsProgram <int?> TryAccept(Reservation reservation)
        {
            return(ReservationsProgram
                   .IsReservationInFuture(reservation)
                   .SelectMany(isInFuture =>
            {
                if (!isInFuture)
                {
                    return new Pure <int?>(null);
                }

                return ReservationsProgram
                .ReadReservations(reservation.Date)
                .SelectMany(reservations =>
                {
                    var reservedSeats = reservations.Sum(r => r.Quantity);
                    if (Capacity < reservedSeats + reservation.Quantity)
                    {
                        return new Pure <int?>(null);
                    }

                    reservation.IsAccepted = true;
                    return ReservationsProgram
                    .Create(reservation)
                    .Select(x => new int?(x));
                });
            }));
        }
        public static async Task <TResult> Run <TResult>(this ReservationsProgram <TResult> prg, IReservationsInstrHandler handler)
        {
            var result = default(TResult);
            var done   = false;

            while (!done)
            {
                switch (prg)
                {
                case Return <TResult> ret:
                    result = ret.Result;
                    done   = true;
                    break;

                case Delay <TResult> delay:
                    prg = delay.Func();
                    break;

                case Await <TResult> _await:
                    prg = await _await.Accept(handler);

                    break;

                default:
                    throw new NotSupportedException($"{prg.GetType().Name}");
                }
            }

            return(result);
        }
        public void Start <TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
        {
            var state = stateMachine;

            this.cont = () =>
            {
                state.MoveNext();
                return(this.prg);
            };
            this.prg = new Delay <TResult>(cont);
        }
        public IReservationsProgram <IMaybe <int> > TryAccept(Reservation reservation)
        {
            return
                (from isInFuture in ReservationsProgram.IsReservationInFuture(reservation)
                 from _ in ReservationsProgram.Guard(isInFuture)

                 from reservations in ReservationsProgram.ReadReservations(reservation.Date)
                 let reservedSeats = reservations.Sum(r => r.Quantity)
                                     from __ in ReservationsProgram.Guard(reservedSeats + reservation.Quantity <= Capacity)

                                     from ___ in ReservationsProgram.Do(() => { reservation.IsAccepted = true; })
                                     from id in ReservationsProgram.Create(reservation)
                                     select id);
        }
 public void AwaitUnsafeOnCompleted <TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
     where TAwaiter : ReservationsInstr
     where TStateMachine : IAsyncStateMachine
 {
     this.prg = awaiter.Await(this.cont);
 }
 public void SetResult(TResult result)
 {
     this.prg = new Return <TResult>(result);
 }