There existing two basic collection types in F#: Array and List. Within this article I want to compare both collection types and I want to help you choose the right one for your programming issues.
An array is a collection with a fixed size. All elements of the array must have same type. It is possible to read and update the elements. The F# array is based on System.Array. Therefore, if you have used arrays in C#, you are familiar with the underlying concept. It is possible to use one dimensional arrays (often called vectors) and multi-dimensional arrays (matrices).
The following source code shows the basic syntax of array commands. To create an array you may use [|…|]. Between the brackets you have to set all elements, separated with semicolon. An element can be read by using .[<index>] (zero based). To set the value of an element you have to use <-.
//create let myArray = [|7;4;1;9|] //read (zero based index, reads element "4") let x = myArray. //write myArray. <- x+1
As I wrote before, arrays may be single or multi-dimensional. Furthermore the multi-dimensional arrays can have two different structures. They might by rectangular or jagged. In rectangular arrays all inner arrays have the same size. In jagged arrays the inner arrays may have different sizes. To access the elements of the inner array you have to use . multiple times. Furthermore for rectangular arrays with two or three dimensions you may use the Array2 and Array3 modules. They offer an easy way to create and access the data of the array.
The following source code shows how to use a jagged array.
//create let jaggedArray = [| [|7|]; [|4;1;9|] |] //read (zero based index, reads element "4") let x = jaggedArray.. //write jaggedArray.. <- x+1
The next example shows how to use a rectangular array, in this case a 2D array (or two dimensional matrix).
//create matrix with 2x2 dimensions and fill with zeros let rectangularArray = Array2D.create 2 2 0 //set values rectangularArray.[0,0] <- 7 rectangularArray.[0,1] <- 4 rectangularArray.[1,0] <- 1 rectangularArray.[1,1] <- 9 //read (zero based index, reads element "4") let x = rectangularArray.[0,1] //write rectangularArray.[0,1] <- x+1
A list is a collection which can grow dynamically. All elements must have the same type. The elements are immutable. To create a list you may use […]. Between the brackets you have to set all elements, separated with semicolon.
You cannot update elements of a list but you may create a new list by adding a new element to the beginning of the list or by concatenating two list.
The following source code shows an example how to create a list.
//create let myList = [7;4;1;9] //read (zero based index, reads element "4") let x = myList. //add element, concatenate two lists let mySecondList = 5::myList let myThirdList = myList @ mySecondList
As shown in the example you may read an element by using the same syntax like we already have used for arrays: myList.[<index>]. But if you work with list you should use another possibility to read elements: recursion and pattern matching. The following source code shows an according example. The sum function uses pattern matching to access the elements of the list.
//create let myList = [7;4;1;9] //calculate sum let rec sum values = match values with |  -> 0 | head::tail -> head + sum(tail) //test let x = sum myList
Array vs. List
The following table shows the main differences between the F# Array and List.
|Mutability of collection||Fixed size||Variable size|
|Mutability of elements||Mutable elements||Immutable elements|
|Syntax to create collection||[|…|]||[…]|
|Syntax to write element||<-||Not supported (immutable elements)|
|Syntax to read element||.[<index>]||Recursion and pattern matching|
Whether you should use a list or an array depends on the use case you want to implement. If both collection types may solve your use case, I recommend the list collection. The list offers pure functional features: immutable elements, pattern matching and recursion. Therefore it allows you to use the advantages of a functional programming language like F