## Desktop Calculator

To understand how a program is built in Objective CAML, it is necessary to develop one. The chosen example is a desktop calculator---that is, the simplest model, which only works on whole numbers and only carries out the four standard arithmetic operations.

To begin, we define the type key to represent the keys of a pocket calculator. The latter has fifteen keys, namely: one for each operation, one for each digit, and the = key.
```# type` `key` ``=`` `Plus` ``|`` `Minus` ``|`` `Times` ``|`` `Div` ``|`` `Equals` ``|`` `Digit` `of` `int` `;;

```
We note that the numeric keys are gathered under a single constructor Digit taking an integer argument. In fact, some values of type key don't actually represent a key. For example, (Digit` ``3``2`) is a possible value of type key, but doesn't represent any of the calculator's keys.

So we write a function valid which verifies that its argument corresponds to a calculator key. The type of this function is key -> bool, that is, it takes a value of type key as argument and returns a value of type bool.

The first step is to define a function which verifies that an integer is included between 0 and 9. We declare this function under the name is_digit:
```# let` `is_digit` ``=`` `function` `x` `->` `(x`>=``0`)` ``&&`` `(x`<=``9`)` `;;`val is_digit : int -> bool = <fun>`

```

We then define the function valid by pattern-matching over its argument of type key:
```# ` `` `let` `valid` `ky` ``=`` `match` `ky` `with` `` `` `` `` `Digit` `n` `->` `is_digit` `n` `` `` `` ``|`` ``_`` `->` `true` `;;`val valid : key -> bool = <fun>`

```
The first pattern is applied when the argument of valid is a value made with the Digit constructor; in this case, the argument of Digit is tested by the function is_digit. The second pattern is applied to every other kind of value of type key. Recall that thanks to typing, the value being matched is necessarily of type key.

Before setting out to code the calculator mechanism, we will specify a model allowing us to describe from a formal point of view the reaction to the activation of one of the device's keys. We will consider a pocket calculator to have four registers in which are stored respectively the last computation done, the last key activated, the last operator activated, and the number printed on the screen. The set of these four registers is called the state of the calculator; it is modified by each keypress on the keypad. This modification is called a transition and the theory governing this kind of mechanism is that of automata. A state will be represented in our program by a record type:
```# type` `state` ``=`` `{` `` `` `lcd` ``:`` `int;` ``(* last computation done   *)`` `` `` `lka` ``:`` `key;` ``(* last key activated      *)`` `` `` `loa` ``:`` `key;` ``(* last operator activated *)`` `` `` `vpr` ``:`` `int` `` ``(* value printed           *)`` `}` `;;

```

Figure 2.6 gives an example of a sequence of transitions.

 state key (0,=,=,0) 3 ¾® (0,3,=,3) + ¾® (3,+,+,3) 2 ¾® (3,2,+,2) 1 ¾® (3,1,+,21) × ¾® (24,*,*,24) 2 ¾® (24,2,*,2) = ¾® (48,=,=,48)

Figure 2.6: Transitions for 3+21*2= .

In what follows we need the function evaluate which takes two integers and a value of type key containing an operator and which returns the result of the operation corresponding to the key, applied to the integers. This function is defined by pattern-matching over its last argument, of type key:
```# let` `evaluate` `x` `y` `ky` ``=`` `match` `ky` `with` `` `` `` `` `Plus` `` `` `->` `x` ``+`` `y` `` `` `` ``|`` `Minus` `` `->` `x` ``-`` `y` `` `` `` ``|`` `Times` `` `->` `x` ``*`` `y` `` `` `` ``|`` `Div` `` `` `` `->` `x` ``/`` `y` `` `` `` ``|`` `Equals` `` `->` `y` `` `` `` ``|`` `Digit` ``_`` `->` `failwith` ``"evaluate : no op"`;;`val evaluate : int -> int -> key -> int = <fun>`

```

Now we give the definition of the transition function by enumerating all possible cases. We assume that the current state is the quadruplet (a,b,Å,d):
• a key with digit x is pressed, then there are two cases to consider:
• the last key pressed was also a digit. So it is a number which the user of the pocket calculator is in the midst of entering; consequently the digit x must be affixed to the printed value, i.e., replacing it with d×10+x. The new state is:
(a,(Digit x),Å,d×10+x)

• the last key pressed was not a digit. So it is the start of a new number which is being entered. The new state is:
(a,(Digit x),Å,x)
• a key with operator Ä has been pressed, the second operand of the operation has thus been completely entered and the calculator has to deal with carrying out this operation. It is to this end that the last operation (here Å) is stored. The new state is:
(Å d,Ä,Ä,a Å d)
To write the function transition, it suffices to translate the preceding definition word for word into Objective CAML: the definition by cases becomes a definition by pattern-matching over the key passed as an argument. The case of a key, which itself is made up of two cases, is handled by the local function digit_transition by pattern-matching over the last key activated.
```# let` `transition` `st` `ky` ``=`` `` `` `` `let` `digit_transition` `n` ``=`` `function` `` `` `` `` `` `` `` `Digit` ``_`` `->` `{` `st` `with` `lka`=`ky;` `vpr`=`st`.`vpr`*``1``0``+`n` `}` `` `` `` `` `` `` ``|`` `` ``_`` `` `` `` `` `` `->` `{` `st` `with` `lka`=`ky;` `vpr`=`n` `}` `` `` `` `` `in` `` `` `` `` `` `match` `ky` `with` `` `` `` `` `` `` `` `` `` `` `Digit` `p` `` `->` `` `digit_transition` `p` `st`.`lka` `` `` `` `` `` `` `` `` ``|`` `` ``_`` `` `` `` `` `` `` `` `` `->` `` `let` `res` ``=`` `evaluate` `st`.`lcd` `st`.`vpr` `st`.`loa` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `in` `{` `lcd`=`res;` `lka`=`ky;` `loa`=`ky;` `vpr`=`res` `}` `` `;;`val transition : state -> key -> state = <fun>`

```
This function takes a state and a key and computes the new state.

We can now test this program on the previous example:
```# let` `initial_state` ``=`` `{` `lcd`=``0`;` `lka`=`Equals;` `loa`=`Equals;` `vpr`=``0`` `}` `;;` ``val initial_state : state = {lcd=0; lka=Equals; loa=Equals; vpr=0}`# let` `state2` ``=`` `transition` `initial_state` `(Digit` ``3`)` `;;`val state2 : state = {lcd=0; lka=Digit 3; loa=Equals; vpr=3}`# let` `state3` ``=`` `transition` `state2` `Plus` `;;`val state3 : state = {lcd=3; lka=Plus; loa=Plus; vpr=3}`# let` `state4` ``=`` `transition` `state3` `(Digit` ``2`)` `;;`val state4 : state = {lcd=3; lka=Digit 2; loa=Plus; vpr=2}`# let` `state5` ``=`` `transition` `state4` `(Digit` ``1`)` `;;`val state5 : state = {lcd=3; lka=Digit 1; loa=Plus; vpr=21}`# let` `state6` ``=`` `transition` `state5` `Times` `;;`val state6 : state = {lcd=24; lka=Times; loa=Times; vpr=24}`# let` `state7` ``=`` `transition` `state6` `(Digit` ``2`)` `;;`val state7 : state = {lcd=24; lka=Digit 2; loa=Times; vpr=2}`# let` `state8` ``=`` `transition` `state7` `Equals` `;;`val state8 : state = {lcd=48; lka=Equals; loa=Equals; vpr=48}`

```

This run can be written in a more concise way using a function applying a sequence of transitions corresponding to a list of keys passed as an argument.

```# let` `transition_list` `st` `ls` ``=`` `List.fold_left` `transition` `st` `ls` `;;`val transition_list : state -> key list -> state = <fun>`# let` `example` ``=`` ``[`` `Digit` ``3`;` `Plus;` `Digit` ``2`;` `Digit` ``1`;` `Times;` `Digit` ``2`;` `Equals` ``]`` `in` `transition_list` `initial_state` `example` `;;`- : state = {lcd=48; lka=Equals; loa=Equals; vpr=48}`

```