Click here to Skip to main content
15,887,350 members
Articles / Programming Languages / F#
Tip/Trick

Simple Calculator In F#

Rate me:
Please Sign up or sign in to vote.
4.33/5 (4 votes)
13 Oct 2015CPOL4 min read 19.6K   397   4   6
A simple calculator written in F# language

Introduction

This tip is a simple calculator program written in F# programming language. The calculator performs simple operations like +, -, * and /.

From this calculator, you can learn various features of F# language used in this calculator program such as match expression, array, accessing array element via (.) and ([ and ]) operator, object type casting, etc. And also, you will be able to know about the use of System.Windows.Forms control classes to create graphical user interface in F# language.

Using the Code

The calculator program has a main window, ten buttons for 0 to 9 number, 4 buttons for doing +, -, *, / operations and two buttons for doing equal and clear operations. The calculator also has a label control as the calculator display.

Here is the main window class of our calculator:

F#
type MainWindow() = 
    inherit Form()

In F# language, class definitions start with the type keyword.

The above class represents the main window of our calculator and it inherits the System.Windows.Forms.Form class.

Here are all the private fields of the MainWindow class:

F#
let btnNumbers :Button array = Array.zeroCreate 10

let btnAdd = new Button()
let btnMin = new Button()
let btnMul = new Button()
let btnDiv = new Button()

let btnEqual = new Button()
let btnClear = new Button()

let lblDisplay = new Label()

let mutable doClear = false

let mutable operation = 0
let mutable operand1 :Int64 = int64 0
let mutable operand2 :Int64 = int64 0

Typically, let binding is used for defining private fields and functions in F# language.

In the above codes, we make all the 0 to 9 numbers buttons as an array of Button class to make things easy. We have made the last four variables mutable because we need to modify those variable at run-time.

The following function is the initializer function of the MainWindow class. This function initializes some basic properties of the window, initializes all the buttons and the display label control. The entry point function of the program will call this function.

F#
member this.Init =
        this.Text <- "Simple Calculator In F#"
        this.Size <- new System.Drawing.Size(270, 400)
        this.FormBorderStyle <- FormBorderStyle.Fixed3D
        this.MaximizeBox <- false
        this.BackColor <- System.Drawing.Color.FromArgb(255, 225, 235)

Then, we initialize the display control which is a label control class of System.Windows.Forms namespace.

F#
lblDisplay.Location <- Point(30, 90)
lblDisplay.Size <- Size(190, 40)
lblDisplay.Text <- "0"
lblDisplay.BackColor <- System.Drawing.Color.White
lblDisplay.Font <- new Font("Arial", 16.0f)
lblDisplay.BorderStyle <- BorderStyle.Fixed3D
lblDisplay.TextAlign <- ContentAlignment.BottomRight

All the 0 to 9 buttons are initialized through a for .. in loop:

F#
for i in 0 .. btnNumbers.Length - 1 do

            btnNumbers.[i] <- new Button()

            btnNumbers.[i].Location <- Point(btnX, btnY)
            btnNumbers.[i].Size <- Size(40, 40)
            btnNumbers.[i].Text <- i.ToString()
            //btnNumbers.[i].BackColor <- System.Drawing.Color.White
            btnNumbers.[i].Click.AddHandler(new System.EventHandler(fun s e -> this.Event_Number_Pressed(s, e)))

            this.Controls.Add(btnNumbers.[i])

            if i = 0 then
                btnY <- btnY - 50
            else
                if i % 3 = 0 then
                    btnX <- 30
                    btnY <- btnY - 50
                else
                    btnX <- btnX + 50

We can see that [ and ] operator is used to access array element. In F# language, you can access array elements through using a dot operator (.) and brackets ([ and ]).

Then we initialize addition, minus, multiply, division, equal and clear operations buttons:

F#
btnAdd.Location <- Point(180, 300)
btnAdd.Size <- Size(40, 40)
btnAdd.Text <- "+"
btnAdd.BackColor <- System.Drawing.Color.FromArgb(187, 208, 185)
btnAdd.Click.AddHandler(new System.EventHandler(fun s e ->this.Event_Operation_Pressed(s, e)))

btnMin.Location <- Point(180, 250)
btnMin.Size <- Size(40, 40)
btnMin.Text <- "-"
btnMin.BackColor <- btnAdd.BackColor
btnMin.Click.AddHandler(new System.EventHandler(fun s e -> this.Event_Operation_Pressed(s, e)))

. . . . . . . . .  . . . . . . .
. . . . . . . . .

And finally, at the end of the init function, we add all the controls to our main window in this way:

F#
this.Controls.Add(lblDisplay)

this.Controls.Add(btnClear)
this.Controls.Add(btnEqual)
this.Controls.Add(btnAdd)
this.Controls.Add(btnMin)
this.Controls.Add(btnMul)
this.Controls.Add(btnDiv)

Now, we will see codes of button click event handler. In this calculator program, we have four kinds of buttons. Equal, clear, mathematical operators and 0 to 9 numbers buttons. So we have made four event handlers for those buttons.

This member function represents click event codes for the operator buttons:

F#
member this.Event_Operation_Pressed(sender : System.Object, e : System.EventArgs) = 

        let btn = this.downcastButton(sender)

        operation <- 
            match btn.Text.[0] with 
            | '+' -> 1
            | '-' -> 2
            | '*' -> 3
            | '/' -> 4
            | _ -> 1   // Default is add operation. But I don't think this will ever happen.  

        doClear <- true

        if operand2 <> int64 0 then
            this.DoOperation()
            operand1 <- Int64.Parse(lblDisplay.Text)

In the above codes, first, we convert the sender parameter from System.Object type to System.Windows.Forms.Button class type. We use a user-defined member function called downcastButton for that purpose.

To determine what kind of operation we should do now, we use an interesting feature of F# language called match expression to make things more clear. The value of operation variable will depend on the first element of sender button text array.

According to MSDN, the syntax of match expression is as follows:

// Match expression.
match test-expression with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

To me, match expression is something like the switch statement of C like language. But of course, match expression is much more easier to use.

When any number button is pressed, if the operation variable is zero, then we add the number to the display label text and we store the number into the operand1 variable.

If the operation variable was not zero, then we also add the number to the display label text and we store the number into the operand2 variable.

Here is the number buttons click event handler:

F#
member this.Event_Number_Pressed(sender : System.Object, e : System.EventArgs) = 
        let btn = this.downcastButton(sender)

        if lblDisplay.Text = "0" then
            doClear <- true

        if doClear = true then
            lblDisplay.Text <- ""
            doClear <- false

        if lblDisplay.Text.Length < 17 then
            if operation = 0 then
                lblDisplay.Text <- lblDisplay.Text + btn.Text
                operand1 <- Int64.Parse(lblDisplay.Text)
            else
                lblDisplay.Text <- lblDisplay.Text + btn.Text
                operand2 <- Int64.Parse(lblDisplay.Text)

When the equal button is pressed, we call a function called DoOperation to calculate the operand1 and operand2 variable value and we show the result into the display label.

The calculation depends on the operation variable value that whether it should be a +, -, *, or / calculation.

Here is the DoOperation function definition:

F#
member this.DoOperation() = 
        if operation = 1 then // Add
            lblDisplay.Text <- (operand1 + operand2).ToString()
        else if operation = 2 then // Min
            lblDisplay.Text <- (operand1 - operand2).ToString()
        else if operation = 3 then // Mul
            lblDisplay.Text <- (operand1 * operand2).ToString()
        else if operation = 4 then // Div
            lblDisplay.Text <- (operand1 / operand2).ToString()

Conclusion

I think making a simple calculator will be a good practice for beginners. Although the calculator has included very simple features, I hope this calculator will help you to improve your skill in F# programming language.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Bangladesh Bangladesh
Hi, I'm Shah Farhad Reza. I'm a desktop and web software developer.

Recently I've developed an web based ERP (Enterprise Resource Planning) Software for a manufacturing company. The software is in use and working effectively fulfilling its goal (Alhamdulillah) - [February 10, 2023]

The areas of my expertise are the followings:

- OS Kernel developing.
- Programming language's compiler design and implement.
- Expert in C, C++ and Visual Basic and have basic knowledge on C#, D, Java.
- A few times used the Microsoft's new language F#.
- SQL Database programming.
- I've basic knowledge on lowest level programming language like assembly.
- Learning Mozilla’s Rust & Google’s GO programming language for software development.
- Code optimization for performance.
- Multi-threaded programming in C/C++ and Java.
- Know various advanced computer algorithm and have used them to develop graphics and simulation programs. Also working with Linear Algebra and keen to learn Quadratic Algebra in future.
- Graphics and Game programming (Both 2D and 3D).

Currently, I'm doing research on programming language and its compiler development. I've made various kind of software and now I want to share my experiences with people.


Comments and Discussions

 
QuestionFirst time i have ever seen any F# code. Pin
Dr Gadgit13-Oct-15 7:07
Dr Gadgit13-Oct-15 7:07 
AnswerRe: First time i have ever seen any F# code. Pin
Farhad Reza13-Oct-15 8:12
Farhad Reza13-Oct-15 8:12 
GeneralRe: First time i have ever seen any F# code. Pin
Dr Gadgit14-Oct-15 5:08
Dr Gadgit14-Oct-15 5:08 
GeneralRe: First time i have ever seen any F# code. Pin
Farhad Reza14-Oct-15 5:26
Farhad Reza14-Oct-15 5:26 
GeneralRe: First time i have ever seen any F# code. Pin
Dr Gadgit14-Oct-15 5:48
Dr Gadgit14-Oct-15 5:48 
GeneralRe: First time i have ever seen any F# code. Pin
Farhad Reza14-Oct-15 6:14
Farhad Reza14-Oct-15 6:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.