public Validated <decimal> SubmitOperationInputAndGetResult(IOperation operationInput) { //Validate, submit input, and get result return(validatedOperationInput(operationInput) .Bind(submitAndGetResult)); //Local functions Validated <IOperation> validatedOperationInput(IOperation input) => isValidOnCurrentState(input) ? new Validated <IOperation>(input) : new StringError("Operation is not currently allowed."); bool isValidOnCurrentState(IOperation input) => FunctionForNewOperation(input, ifNoOperands: () => IsAdditionalValueValidOnCurrentState(), ifSingleOperand: () => HasReceivedValues(), ifMultipleOperandsWithoutActiveOperation: () => HasReceivedValues(), ifMultipleOperandsWithActiveOperation: () => IsActiveOperationComplete()); Validated <decimal> submitAndGetResult(IOperation input) => validatedEvaluationResult(input) .Map(x => saveAndGetResult(input, x)); Validated <decimal> validatedEvaluationResult(IOperation input) => FunctionForNewOperation(input, ifNoOperands: () => input.ResultForOperands(ImmutableList <decimal> .Empty), ifSingleOperand: () => input.ResultForOperands(ListWithSingleValue(CurrentState.Values.Last())), ifMultipleOperandsWithoutActiveOperation: () => new Validated <decimal>(null), ifMultipleOperandsWithActiveOperation: () => CurrentState.ActiveOperation.ResultForOperands(CurrentState.Values)); decimal saveAndGetResult(IOperation evaluatedOperation, decimal resultingValue) => LatestValueOfState(CurrentState = resultingState(evaluatedOperation, resultingValue)); ICalculatorState resultingState(IOperation evaluatedOperation, decimal resultingValue) => CalculatorStateFactory.NewCalculatorState(resultingValues(evaluatedOperation, resultingValue), newOperation(evaluatedOperation)); IImmutableList <decimal> resultingValues(IOperation evaluatedOperation, decimal resultingValue) => FunctionForNewOperation(evaluatedOperation, ifNoOperands: () => CurrentValuesPlusNewValue(resultingValue), ifSingleOperand: () => CurrentValuesWithLastReplaced(resultingValue), ifMultipleOperandsWithoutActiveOperation: () => CurrentState.Values, ifMultipleOperandsWithActiveOperation: () => ListWithSingleValue(resultingValue)); IOperation newOperation(IOperation evaluatedOperation) => FunctionForNewOperation(evaluatedOperation, ifNoOperands: () => CurrentState.ActiveOperation, ifSingleOperand: () => CurrentState.ActiveOperation, ifMultipleOperandsWithoutActiveOperation: () => evaluatedOperation, ifMultipleOperandsWithActiveOperation: () => evaluatedOperation); }
public Calculator(ICalculatorStateFactory calculatorStateFactory) { //Inject readonly dependencies CalculatorStateFactory = calculatorStateFactory; //Initialize mutable state CurrentState = CalculatorStateFactory.NewCalculatorState(initialValues(), initialOperation()); //Local functions IImmutableList <decimal> initialValues() => ImmutableList <decimal> .Empty; IOperation initialOperation() => null; }
private static ICalculatorState GetNewState(ICalculatorState state, char inPressedDigit) { try { if (LexingHelper.IsNumber(inPressedDigit)) { return(state.PressedOperand(inPressedDigit)); } return(state.PressedOperation(Operations.From(inPressedDigit))); } catch (Exception e) { //log return(new ErrorState()); } }
public Validated <decimal> SubmitValueInputAndGetResult(decimal valueInput) { //Validate, submit input, and get result return(validatedValueInput(valueInput) .Map(submitAndGetResult)); //Local functions Validated <decimal> validatedValueInput(decimal input) => IsAdditionalValueValidOnCurrentState() ? new Validated <decimal>(input) : new StringError("Value is not currently allowed."); decimal submitAndGetResult(decimal input) => LatestValueOfState(CurrentState = stateAfter(input)); ICalculatorState stateAfter(decimal input) => CalculatorStateFactory.NewCalculatorState(CurrentValuesIncluding(input), activeOperation()); IImmutableList <decimal> CurrentValuesIncluding(decimal input) => CurrentState.Values.Add(input); IOperation activeOperation() => CurrentState.ActiveOperation; }
public Validated <decimal> SubmitEqualsRequestAndGetResult() { //Validate, submit, and get result return(validatedEqualsRequest() .Bind(submitEqualsRequestAndGetResult)); //Local functions Validated validatedEqualsRequest() => isEqualsRequestValidForCurrentState() ? new Validated() : new StringError("Equals request is not currently allowed."); bool isEqualsRequestValidForCurrentState() => HasActiveOperation() && IsActiveOperationComplete(); Validated <decimal> submitEqualsRequestAndGetResult() => validatedEqualsRequestResult() .Map(saveAndGetResult); decimal saveAndGetResult(decimal result) => LatestValueOfState(CurrentState = stateWithEqualsRequestResult(result)); ICalculatorState stateWithEqualsRequestResult(decimal equalsRequestResult) => CalculatorStateFactory.NewCalculatorState(ListWithSingleValue(equalsRequestResult), null); Validated <decimal> validatedEqualsRequestResult() => CurrentState.ActiveOperation.ResultForOperands(CurrentState.Values); }
private decimal LatestValueOfState(ICalculatorState calculatorState) => calculatorState.Values.Last();
public Display(ICalculatorState state) { _num = state.GetContext().Num; }
public void Press(char inPressedDigit) { _state = GetNewState(_state, inPressedDigit); _displayState = new Display(_state).Format(); }