Dedicated functions

Functions available only for their dedicated type

List module

Cons 1 :: [2; 3]

  • Item added to top of list

  • List appears in reverse order πŸ˜•

  • But operation efficient: in O(1) (Tail preserved) πŸ‘

Append [1] @ [2; 3]

  • List in normal order

  • But operation in O(n) ❗ (New Tail at each iteration)

Map module

Map.add, Map.remove

Map.add key value β†’ Safe add: replace existing value of existing key β†’ Parameters key value curried, not a pair (key, value)

Map.remove key β†’ Safe remove: just return the given Map if key not found

let input = Map [ (1, "a"); (2, "b") ]

input
|> Map.add 3 "c"  // β†’ `map [(1, "a"); (2, "b"); (3, "c")]`
|> Map.add 1 "@"  // β†’ `map [(1, "@"); (2, "b"); (3, "c")]`
|> Map.remove 2   // β†’ `map [(1, "@"); (3, "c")]`

Map.change

Map.change key (f: 'T option -> 'T option)

  • All-in-one function to add, modify or remove the element of a given key

  • Depends on the f function passed as an argument

Key

Input

f returns None

f returns Some newVal

-

-

≑ Map.remove key

≑ Map.add key newVal

Found

Some value

Remove the entry

Change the value to newVal

Not found

None

Ignore this key

Add the item (key, newVal)

Example: Lexicon β†’ Build a Map to classify words by their first letter capitalized

☝️ Previous example for demonstration purpose only. β†’ Better implementation:

Map.containsKey vs Map.exists

Map.containsKey (key: 'K) β†’ Indicates whether the key is present

Map.exists (predicate: 'K -> 'V -> bool) β†’ Indicates whether an entry (as key value parameters) satisfies the predicate β†’ Parameters key value curried, not a pair (key, value)

Seq Module

Seq.cache

Seq.cache (source: 'T seq) -> 'T seq

Sequences are lazy: elements (re)evaluated at each time iteration β†’ Can be costly πŸ’Έ

Invariant sequences iterated multiple times β†’ Iterations can be optimized by caching the sequence using Seq.cache β†’ Caching is optimized by being deferred and performed only on first iteration

⚠️ Recommendation: Caching is hidden, not reflected on the type ('T seq) β†’ Only apply caching on a sequence used in a very small scope β†’ Prefer another collection type otherwise

String type

To manipulate the characters in a string, several options are available.

Seq module

The string type implements Seq<char>. β†’ We can therefore use the functions of the Seq module.

Array module

ToCharArray() method returns the characters of a string as a char array. β†’ We can therefore use the functions of the Array module.

String module

There is also a String module (from FSharp.Core) offering a number of interesting functions that are individually more powerful than those of Seq and Array:

Examples:

☝️ Note: after open System, String stands for 3 things that the compiler is able to figure them out:

  • (new) String(...) constructors

  • String. gives access to all functions of the String module (in camelCase)...

  • ... and static methods of System.String (in PascalCase)

Array2D

Instead of working with N-level nested collections, F# offers multidimensional arrays (also called matrixes). However, to create them, there's no specific syntax: you have to use a create function.

Let's take a look at 2-dimensional arrays.

Type

The type of a 2-dimensional array is 't[,] but IntelliSense sometimes just gives 't array which is less precise, no longer indicating the number of dimensions.

Construction

array2D creates a 2-dimensional array from a collection of collections all of the same length.

Array2D.init generates an array by specifying: β†’ Its length according to the 2 dimensions N and P β†’ A function generating the element at the two specified indexes.

Access by indexes

Lengths

Array2D.length1 and Array2D.length2 return the number of rows and columns.

Slicing

Syntax for taking only one horizontal and/or vertical slice, using the .. operator and the wilcard * character to take all indexes.

This feature offers a lot of flexibility. As with a collection of collections, a matrix allows access by row (matrix[row, *] vs list[row]). A matrix also allows direct access by column (matrix[*, col]), which is not possible with a collection of collections without first transposing it - see transpose function (doc).

Other use cases

Other functions: πŸ”— https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-array2dmodule.html

Last updated

Was this helpful?