Types
Type List
ListImplemented as a linked list:
1 list = 1 element (Head) + 1 sub-list (Tail)
Construction using
::Cons operator
To avoid infinite recursion, we need an "exit" case:
β Empty list named Empty and noted []
π Generic and recursive union type:
type List<'T> =
| ( [] )
| ( :: ) of head: 'T * tail: List<'T>βοΈ Note: this syntax with cases as operator is only allowed in FSharp.Core.
Type alias
List(big L) refers to the Fβ― type or its companion module.list(small l) is an alias of Fβ―'sListtype, often used with OCaml notation: βlet l : string list = ...
β οΈ Warnings:
β After
open System.Collections.Generic:Listis the Cβ― mutable list, hiding the Fβ― type!The
ListFβ― companion module remains available β confusion!
π‘ Use the
ResizeArrayalias to reference the Cβ― list directlyno need for
open System.Collections.Genericπ
Immutability
A List is immutable:
β It is not possible to modify an existing list.
Adding an element in the list:
= Cheap operation with the Cons operator (::)
β Creates a new list with:
β’ Head = given element
β’ Tail = existing list
π·οΈ Related concepts:
linked list
recursive type
Literals
0
[]
[]
Empty
1
[1]
1 :: []
Cons (1, Empty)
2
[2; 1]
2 :: 1 :: []
Cons (2, Cons (1, Empty))
3
[3; 2; 1]
3 :: 2 :: 1 :: []
Cons (3, Cons (2, Cons (1, Empty)))
(*) We can verify it with SharpLab.io :
Initialisation
Exercices πΉοΈ
1. Implement the rev function
β Inverts a list: rev [1; 2; 3] β‘ [3; 2; 1]
2. Implement the map function
β Transforms each element: [1; 2; 3] |> map ((+) 1) β‘ [2; 3; 4]
π‘ Hints
β Use empty list [] or Cons head :: tail patterns
β Write a recursive function
We can verify that it's working in FSI console:
π‘ Bonus: verify the tail recursion with sharplab.io
Type Array
ArraySignature: 'T array (recommended) or 'T[] or 'T []
Main differences compared to the List:
Fixed-size
Fat square brackets
[| |]for literalsMutable β
Access by index in
O(1)π
π‘ Slicing works also with string: "012345"[1..3] β‘ "123"
Alias ResizeArray
ResizeArrayAlias for System.Collections.Generic.List<T> BCL type
Advantages π
No need for
open System.Collections.GenericNo name conflicts on
List
Notes βοΈ
Do not confuse the alias
ResizeArraywith theArrayFβ― type.ResizeArrayis in Fβ― a better name for the BCL genericList<T>Closer semantically and in usage to an array than a list
Type Seq
SeqDefinition: Series of elements of the same type
't seq β‘ Seq<'T> β‘ IEnumerable<'T>
Lazy: sequence built gradually as it is iterated β All other collections built entirely from their declaration
Syntax
seq { items | range | comprehension }
Infinite sequence
2 options to write an infinite sequence
Use
Seq.initInfinitefunctionWrite a recursive function to generate the sequence
Option 1
Seq.initInfinite function
Signature:
(initializer: (index: int) -> 'T) -> seq<'T>Parameter:
initializeris used to create the specified index element (>= 0)
Option 2
Recursive function to generate the sequence
Type Set
SetSelf-ordering collection of unique elements (without duplicates)
Implemented as a binary tree
Informations
β count, minElement, maxElement
Operations
β
Difference
-
Set.difference
Set.differenceMany
βͺ
Union
+
Set.union
Set.unionMany
β©
Intersection
Γ
Set.intersect
Set.intersectMany
Examples:
Type Map
MapAssociative array { Key β Value } β Cβ― immutable dictionary
Access/Lookup by key
Dictionaries
dict function
dict functionBuilds an
IDictionary<'k, 'v>from a sequence of key/value pairsThe interface is error prone: the dictionary is immutable β
readOnlyDict function
readOnlyDict functionBuilds an
IReadOnlyDictionary<'k, 'v>from a sequence of key/value pairsThe interface is honest: the dictionary is immutable
Recommendation
dict returns an object that does not implement fully IDictionary<'k, 'v>
β Violate the Liskov's substitution principleβ
readOnlyDict returns an object that respects IReadOnlyDictionary<'k, 'v>
π Prefer readOnlyDict to dict when possible
KeyValue active pattern
KeyValue active patternUsed to deconstruct a KeyValuePair dictionary entry to a (key, value) pair
Lookup performance
π High Performance Collections in Fβ― β’ Compositional IT (2021)
Dictionary vs Map
Dictionary vs MapreadOnlyDict creates high-performance dictionaries
β 10x faster than Map for lookups
Dictionary vs Array
Dictionary vs Array~ Rough heuristics
β The Array type is OK for few lookups (< 100) and few elements (< 100)
β Use a Dictionary otherwise
Map and Set vs IComparable
Map and Set vs IComparableOnly works if elements (of a Set) or keys (of a Map) are comparable!
Examples:
F# functional type: tuple, record, union
Structs:
Classes implementing IComparable... but not IComparable<'T> π€·
Last updated
Was this helpful?