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) (
Tailpreserved) π
Append [1] @ [2; 3]
List in normal order
But operation in O(n) β (New
Tailat each iteration)
Map module
Map.add, Map.remove
Map.add, Map.removeMap.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.changeMap.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
ffunction 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 vs Map.existsMap.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.cacheSeq.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
Misleading type
Seq.cache does not change the visible type: it's still seq.
Prosπ
We can use directly
Seqmodule functions.
Cons β οΈ
We don't know that the sequence has been cached.
Recommendation βοΈ
Limit the scope of such cached sequences.
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(...)constructorsString.gives access to all functions of theStringmodule (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?