In F#, collections are fundamental data structures that allow you to store and manipulate groups of values. The three primary types of collections in F# are Lists, Arrays, and Sequences. Each has its own characteristics and use cases.

Lists

Characteristics

  • Immutable: Once created, the elements of a list cannot be changed.
  • Linked List: Each element points to the next, making it efficient for sequential access but not for random access.

Syntax and Examples

Creating Lists

let emptyList = []
let listOfNumbers = [1; 2; 3; 4; 5]
let listOfStrings = ["apple"; "banana"; "cherry"]

Accessing Elements

let firstElement = List.head listOfNumbers  // 1
let restOfList = List.tail listOfNumbers    // [2; 3; 4; 5]

Common Operations

let newList = 0 :: listOfNumbers            // [0; 1; 2; 3; 4; 5]
let concatenatedList = listOfNumbers @ [6; 7; 8]  // [1; 2; 3; 4; 5; 6; 7; 8]
let mappedList = List.map (fun x -> x * 2) listOfNumbers  // [2; 4; 6; 8; 10]

Practical Exercise

Create a list of the first 10 natural numbers and then create a new list where each number is squared.

Solution

let naturalNumbers = [1..10]
let squaredNumbers = List.map (fun x -> x * x) naturalNumbers
// squaredNumbers = [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]

Arrays

Characteristics

  • Mutable: Elements can be changed after the array is created.
  • Fixed Size: The size of the array is determined at creation and cannot be changed.
  • Efficient for random access.

Syntax and Examples

Creating Arrays

let emptyArray = [| |]
let arrayOfNumbers = [| 1; 2; 3; 4; 5 |]
let arrayOfStrings = [| "apple"; "banana"; "cherry" |]

Accessing and Modifying Elements

let firstElement = arrayOfNumbers.[0]  // 1
arrayOfNumbers.[0] <- 10               // arrayOfNumbers = [| 10; 2; 3; 4; 5 |]

Common Operations

let newArray = Array.append arrayOfNumbers [| 6; 7; 8 |]  // [| 10; 2; 3; 4; 5; 6; 7; 8 |]
let mappedArray = Array.map (fun x -> x * 2) arrayOfNumbers  // [| 20; 4; 6; 8; 10 |]

Practical Exercise

Create an array of the first 10 natural numbers and then create a new array where each number is squared.

Solution

let naturalNumbers = [| 1..10 |]
let squaredNumbers = Array.map (fun x -> x * x) naturalNumbers
// squaredNumbers = [| 1; 4; 9; 16; 25; 36; 49; 64; 81; 100 |]

Sequences

Characteristics

  • Lazy Evaluation: Elements are computed on demand.
  • Can represent infinite sequences.
  • Suitable for large or infinite data sets where you don't need all elements at once.

Syntax and Examples

Creating Sequences

let emptySeq = Seq.empty
let seqOfNumbers = seq { 1..5 }
let seqOfStrings = seq { yield "apple"; yield "banana"; yield "cherry" }

Accessing Elements

let firstElement = Seq.head seqOfNumbers  // 1
let restOfSeq = Seq.tail seqOfNumbers     // seq [2; 3; 4; 5]

Common Operations

let newSeq = Seq.append seqOfNumbers (seq { 6..8 })  // seq [1; 2; 3; 4; 5; 6; 7; 8]
let mappedSeq = Seq.map (fun x -> x * 2) seqOfNumbers  // seq [2; 4; 6; 8; 10]

Practical Exercise

Create a sequence of the first 10 natural numbers and then create a new sequence where each number is squared.

Solution

let naturalNumbers = seq { 1..10 }
let squaredNumbers = Seq.map (fun x -> x * x) naturalNumbers
// squaredNumbers = seq [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]

Summary

In this section, we explored the three primary types of collections in F#: Lists, Arrays, and Sequences. We learned about their characteristics, how to create and manipulate them, and their common operations. We also provided practical exercises to reinforce the concepts. Understanding these collections is crucial for effective data manipulation and functional programming in F#.

© Copyright 2024. All rights reserved