F# - For And While Loop Concepts

Introduction

Programming languages provide various control structures that affect the order of code execution.

There are 3 control structures:

  • Sequential control
  • Selection control
  • Iteration control

However, this article will focus on the area of iteration control structure, which is commonly known as loops.

That’s why in this article we’ll discuss the two types of F#’s loops: the for loop and the while loop.

Before we see the examples, code samples are written in .NET 6 and the project is a test project using Xunit.

I also recommend downloading the sample project before going through the examples.

The For Loop

The for loops have two types of expression: for ... to and for ... in.

The for...to this feature iterates over a range of values, while for...in it is more like a for each loop of C# or in other .NET languages as it loops over an enumerable collection.

The for...to Expression/Loop

The for...to expression or loop, its range can be either forward or reverse or generated via function. 

Let’s see some examples. 

Forward loop

[<Theory>]
[<InlineData(0, 10)>]
let ``for_to_loop_test`` (count: int, countEnd: int)=
	//let's start with a simple for.. to loop
	for i = count to countEnd do 
		let message = $"{i}" 
		output.WriteLine message
		Assert.True( i >=0 && i <= 10)
		//output 0 1 2 3 4 5 6 7 8 9 10

The example above starts from 0 and ends at 10 and as it is iterated it actually outputs the value of the variable i to the console. 

Asserting whether the counter is between the range of 0 and 10.

Reverse loop

[<Theory>]
[<InlineData(10, 0)>]
let ``for_to_loop_reverse_test`` (count: int, countEnd: int) =
	for counter = count downto countEnd do 
		let message = $"{counter}"
		output.WriteLine message
		Assert.True( counter >=0 && counter <= 10)
		//output 10 9 8 7 6 5 4 3 2 1 0

The example above starts from 10 and ends at 0 as it iterates it actually outputs the value of the counter to the console.

Asserting whether the counter is between the range of 10 and 0. 

Define the start and end values in the loop

[<Fact>]
let ``for_to_loop_with_start_and_end_function_value`` () = 
	let getRandomNumber startNum endNum  =
		let random = System.Random()
		startNum *  random.Next(startNum,endNum)

	for counter = getRandomNumber 1 5 to getRandomNumber 5 10 do
		let message = $"{counter}"
		output.WriteLine(message)
		Assert.True(counter >= 1 && counter<= 500)

The example above sets the start and end values from the getRandomNumber function and then randomly generates a number within its range. 

Asserting whether the counter is between the range of 1 and  500.

The for...in Expression/Loop

This expression is commonly used for iterating over an enumerable collection, let's see some examples. 

[<Fact>]
let ``for_in_loop_test`` () =
	let companies = [|"Apple"; "Microsoft"; "Google"; "Amazon"|]
	for company in companies  do 
		let message = $"{company}"
		output.WriteLine(message)
		Assert.True(Array.Exists(companies, fun element -> element = message))
		//output Apple Microsoft Google Amazon

The example above iterates over the companies array and outputs the name.

However, we have asserted the existence of the company name using the Array.Exists method for verification. 

We can use mutable variables inside the for...in loop body, let's see an example. 

[<Fact>]
let ``for_in_loop_with_mutable_variable_inside_test`` () =
	
	let companies = [|"Apple"; "Microsoft"; "Google"; "Amazon"|]

	let func_loop_with_mutable_counter = 
		let mutable counter = 0
		for _ in companies do
			let message = $"At index {counter} is {companies.[counter]}"
			output.WriteLine(message)
			Assert.True(not((companies |> Array.findIndex(fun element -> element = companies.[counter])) = -1))
			counter <- counter + 1
            //output Apple Microsoft Google Amazon
	()

In the example above we have shown how we can use a mutable variable inside the for... in the code block and it is almost the same as the previous code sample. 

However, the assertion is different.

In the example above we have to check whether the element (company name) is within the array using the Array.findIndex method.

The While Loop

This kind of loop is used for iteration as long as a specified condition is met.

The condition is being evaluated, and if it is true, the body will be evaluated/executed.

The evaluation/execution will continue until the condition is false. 

Let's see an example. 

[<Fact>]
let ``while_loop_test`` () = 
	
	let mutable isTrue = true
	let mutable counter = 0 

	while isTrue do 
		if counter < 10 then 
			counter <- counter + 1
		else 
			isTrue <- false 
		let message = $"Current counter is: {counter} and isTrue is still {isTrue}"
		Assert.True(counter <= 10)
		output.WriteLine(message)
	()
     //output
     //Current counter is: 1 and isTrue is still True
     //Current counter is: 2 and isTrue is still True
     //Current counter is: 3 and isTrue is still True
     //Current counter is: 4 and isTrue is still True
     //Current counter is: 5 and isTrue is still True
     //Current counter is: 6 and isTrue is still True
     //Current counter is: 7 and isTrue is still True
     //Current counter is: 8 and isTrue is still True
     //Current counter is: 9 and isTrue is still True
     //Current counter is: 10 and isTrue is still True
     //Current counter is: 10 and isTrue is still False

The example above is a classic while loop example.

However, we have used mutable variables such as the isTrue and counter to show that we can use mutable variables within a block code of a while loop.

Conclusion

In this post, we have seen how we can use for and while loops using the F# language. I hope you have enjoyed this article as much as I have enjoyed writing it. Stay tuned for more.

Until next time, happy programming!


Similar Articles