List-Like Expressions in F# 2.0

posted in: Language Features | 0

F# provides literal expressions for tuples, F# lists, arrays, sequences (enumerables) and other generic types. The elements of a tuple expression are separated by commas. The elements of all other kinds of list-like expressions are separated by semicolons.

F# Expression F# Type Representation C# Type Representation
17, 3, 8 int * int * int Tuple<int, int, int>
[17; 3; 8] int list FSharpList<int>
[|17; 3; 8|] int[] int[]
seq {yield 17; yield 3; yield 8} int seq IEnumerable<int>

Note that F# lists should not be exposed to non-F# clients, because they do not have the corresponding syntactic constructs (e.g. :: operator, pattern matching, etc.).

The expressions can be nested deliberately:

F# Nested Expression F# Type Representation C# Type Representation
[17, 3, 8] (int * int * int) list FSharpList<Tuple<int, int, int>>
[|17, 3, 8|] (int * int * int)[] Tuple<int, int, int>[]
[|[|17; 3; 8|]; [|5; 2|]|] int[][] int[][]
array2D [[1; 5]; [7;9]] int[,] int[,]
[|array2D [[1; 3]; [1; 3]]|] int[,][] int[][,]
[|2.7M, true; 3.9M, false|] (decimal * bool)[] Tuple<decimal, bool>[]
(1, 'c'), (3.3, 20I, "abc") (int * char) * (float * bigint * string) Tuple<Tuple<int, char>, Tuple<double, BigInteger, string>>

Note that in F#, jagged multidimensional arrays are represented in reverse order compared to C#: The F# type int[,][] corresponds to the C# type int[][,]. This is to stay consistent with other F# postfix type names, such as int option list, which represents instances like [None; Some(1); Some(2)].

When each element is put on its own line, the semicolons can be ignored, as in this array of type int[]:

[| 17
   3
   8 |]

F# features many more kinds of expressions to simplify working with list-like types. The following range expression defines an IEnumerable<decimal> from 3 to 1275, with steps of 0.25 in between: 3, 3.25, 3.50, 3.75...:

seq { 3M .. 0.25M .. 1275M }

The following code defines an array of type int[] with squares of positive whole numbers: 1, 4, 9, 16, ...

[| for i in 1 .. 1000 -> i * i |]

All list-like types in F# are supported by a wealth of keywords, symbols and operators and helper functions in FSharp.Core.dll. The following code defines an "infinite" IEnumerable<UInt64> of binomial results, calculated from each consecutive pair of natural numbers starting at zero: 1, 9, 25, 49, ...:

Seq.initInfinite uint64
|> Seq.pairwise
|> Seq.map(fun (a, b) -> pown (a + b) 2)

Further information on list-like expressions in F# can be found in the F# 2.0 language specification and F# language reference.