Introduction to Lists
A list is an ordered collection of related values and is equivalent to a Linked List data structure used in many other Languages. F# lists are a simple collection type that is built into F#. F# provides the module Microsoft.Fsharp.Collections.List for common operations on Lists. This module is imported automatically by F#, so the List module is already accessible from every F# application.
F# lists are used in functional programming. Lists play an important role in Functional Programming. In functional programming (F#) lists are actually a linked list of the singly linked list variety. Lists can only contain members of the same type; you have the ability to create a list of an object type. Lists are a built-in data structure that is basically a concatenation of the Head and Tail. The head is the First element and the Tail is the remainder of the List.
An F# list can be an Empty List, a List with a value concatenated to it. A value can be concatenated to the front of a F# list using a built-in operator that consists of two colons (::), pronounced "cons". The following table showing a List being defined starting with an empty List on the First Row.
List related Language Constructs and Operators
Expressions/Operator |
Description |
Example |
[] |
Showing an Empty List |
[] |
expr ::expr |
" cons" an element with a List |
2 :: [3;4] |
[expr;...;expr] |
A List value |
[3 ; 4 ; 5] |
[expr .. expr] |
A range of Integers |
[1 .. 99] |
[for Y in List -> expr] |
A generated List |
[for Y in 1 .. 99 -> Y * Y] |
expr @ expr |
Concatenates two Lists |
[3 ; 4] @ 2 |
Empty List
The very simplest List you can create or use is an Empty List, represented by empty square brackets.
let emptyList = []
// the empty list, head = tail = []
// By Default, the empty list is of type 'T
// If it contains an element, the list is of a fixed type
" cons"
If you want to add an Element to the head or start of a list, you use the right associative cons operator(::). The List in which you want to add an element to can be empty or non empty.
//example "cons"
let list0 = []
let list1 = "colors" :: []
let list2 = "red" :: list1
let list3 = "blue" :: list2
let list4 = "black" :: "olive" :: "pink" :: []
Fixed value List
If you want to create a List that contains elements, then individual elements can be enumerated by a separate semicolon like below.
let names = ["angle"; "jhon"; "denni"]
// list with 3 string elements (head = angle, tail = denni)
concatenated List
A new List can be built by two existing Lists by using @ operator to concatenate them together. You can concatenate like below.
let evenNumbers=[2;4;6;8;10] //separate List 1
let otherNumbers=[11;13] // Separate List 2
let numbers=3::(evenNumbers @ otherNumbers);; //concatenated List From 1 and 2
Ranges
Ranges can be defined in a list as in the following form:
[start_element..step..end_element]
Where start_element is the first element in the List step (it is optioanl) and it is a "Count By" parameter and the end element is the last value. Both Start and End elements will always display in the List that F# constructs, because both are inclusive elements.
// Ranges In List
let digits = [2..20]
let alphabet = ['D'..'S']
let mul3 = [4..4..132]
let evens = [0..2..28]
Generators
Another form of List comprehension used extensively in functional programming is Generators. Generators can be defined in the following form.
[for <identifier> in collection -> expr] or
[for <identifier> in collection do ... yield expr]
Both forms are used in Generators. The first form uses a lambda expression to generate the List elements like below.
let squares = [for i in 1..10 -> i * i] // squares of 1 to 10
Second form for Generators.
let evenumsqr = [for i in 1..10 do if i % 2 = 0 then yield i * i] //squares of even numbers
Syntax for List creation-
let emptyList=[]
let oneElement= "ram" :: []
let twoElement= "ram" :: "shyam" :: []
Some List Examples
let evenNumbers=[2;4;6;8;10]
let otherNumbers=[11;13]
let numbers=3::(evenNumbers @ otherNumbers);;
Results
val evenNumbers : int list = [2; 4; 6; 8; 10]
val otherNumbers : int list = [11; 13]
val numbers : int list = [3; 2; 4; 6; 8; 10; 11; 13]
It's important to note that lists are immutable; the "cons" :: and "append" @ operations do not modify the original lists; instead they create new Lists. You can see this in the following example.
Examples-
let names=["eddie";"jenni";"jolly"];;
Result
val names : string list = ["eddie"; "jenni"; "jolly"]
Example
"kathelyn" :: names;;
Result
val it : string list = ["kathelyn"; "eddie"; "jenni"; "jolly"]
Example
names;;
Result
val it : string list = ["eddie"; "jenni"; "jolly"]
The things which make F# list different from .NET Array and Generic List in the System.collections.Generic namespace.
Features |
Generic List |
Arrays |
F# List |
Add new Element |
Yes |
No |
No |
Element Lookup |
O(1) fast |
O(1) fast |
O(n) slow |
Modify Elements |
Yes |
Yes |
No |
List module Functions
There are a number of built-in functions for manipulating a List.
-
list.hd- Returns the first element or head of a list.
-
list.tl- Returns the tail of the first element. The list of items after the first element.
-
list.length- Returns the length of the List.
-
list.rev- Reverses a list and makes a copy of the entire list.
-
list.find- This takes a Boolean function and returns the first element where that function returns true. If it doesn't find an element it will throw an exception.
-
list.filter- Takes a function and produces a new list with only the items on which the function returns true. This function filters out the list as you request.
A complete Example for List-
Showing all types of List.
// the empty list
let emptyList = []
// list of one item
let newItem = "red " :: []
// list of two items
let oldItem = "black " :: "blue " :: []
// list of two items
let shortHand = ["orange "; "pairs "]
// concatenation of two lists
let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "
// list of objects
let objList = [box 1; box 2.0; box "three"]
// print the lists
let main() =
printfn "%A" emptyList
printfn "%A" newItem
printfn "%A" oldItem
printfn "%A" shortHand
printfn "%A" twoLists
printfn "%A" objList
// call the main function
main()
Output-
Summary
In this article I have covered the concept of F# Lists.