private static Option <IEnumerable <Coin> > CalculateChange(ChangeCalculationState state) =>
        state.IsChangePaidOut
                ? new Some <IEnumerable <Coin> >(state.CalculatedChange)
                : state.CoinBeingProcessed
        .Map(coin =>
        {
            state.UseAsMuchAsPossible(coin);

            return(CalculateChange(state.ForNextCoin())
                   .TryReduce(() => Backtrack(state)));
        })
        .Reduce(None.Value);
        private static Option <IEnumerable <Coin> > Backtrack(ChangeCalculationState state) =>
        state.CoinBeingProcessed
        .Map(coin =>
        {
            if (!state.IsUsed(coin))
            {
                return(None.Value);
            }

            state.Unuse(coin);

            return(CalculateChange(state.ForNextCoin())
                   .TryReduce(() => Backtrack(state)));
        })
        .Reduce(None.Value);
 public static Option <IEnumerable <Coin> > ChangeFor(this IEnumerable <Coin> coins, int amount) =>
 CalculateChange(ChangeCalculationState.Initialize(coins, amount));