Some basics of F#
#light
This directive (hash light) is used to simplify the F# syntax. Meaning the syntax is a little less verbose and removes aspects of the OCaml compatibility.
Immutable by default
By default “variables” are really just “values” as they are immutable by default so
let n = 100
initializes n to the value 100 and you cannot now alter n.
However we can mark a value as mutable and thus is can be altered, for example
let mutable n = 100 n <- n + 1
n is set to be a mutable type and n <- n + 1 is the assignment line of code, assigning n the new value of n + 1.
Assignment operator
As mentioned above, F# values are immutable, by marking them as mutable we can assign values to them. The assignment operator is not = but is <-, for example [code language="fsharp"] let mutable n = 10 // initializes n the value 10 n <- 100 // assignment of the value 100 [/code] ignore
Some functions return values which we might not actually wish to use. For example the following uses List.map to simply output the items in the array urls
let urls = ["http://www.bbc.co.uk"; "http://www.google.co.uk"; "http://www.amazon.co.uk"] let f x = printfn "%s" x List.map f urls
But the compiler will show a warning This expression should have type ‘unit’, but has type ‘unit list’. Use ‘ignore’ to discard the result of the expression, or ‘let’ to bind the result to a name for the line List.map f urls. To fix this either change this line to
let o = List.map f urls
or pipe the result to ignore as per
List.map f urls |> ignore
We can also use the following syntax
ignore(List.map f urls)
Semi-colon and commas in lists and arrays
To declare a list value in F# we use a semi-colon to denote each value of a list for example
let evens = [2;4;6;8;10;12]
This will create a val evens : int list = [2; 4; 6; 8; 10; 12]
Alternatively using a comma as per
let evens = [2,4,6,8,10,12]
This will create a val evens : (int * int * int * int) list = [(2, 4, 6, 8)]. The difference here is that with the comma we’re creating a tuple containing integers, not a list of integers.
Collection Types
List
A list is declared as
let list = [2;4;6;8;10]
Lists are ordered, immutable data of the same type.
Array
An array is declared as
let array = [|2;4;6;8;10|]
Array’s are fixed-size, zero based values of the same type.
Sequence
A sequence is declared as
let s = seq { 0 .. 10 .. 100 }
A sequence is a series of values of the same type.
Lambda expressions and anonymous functions
Anonymous functions are declared as follows
fun parameter-list -> expression
For example we might use an anonymous function in a List.map as follows
let urls = ["http://www.bbc.co.uk"; "http://www.google.co.uk"; "http://www.amazon.co.uk"] List.map (fun x -> printfn "%s" x) urls
Comments
Single line comments are denoted in the same way as C# i.e.
// This is a comment
Multi-line comments are denoted using (*..*), i.e.
(* This is a comment block *)
Loops
The F# equivalent of a foreach
let a = [0 .. 6] for i in a do printfn "%d" i
The for loop
for i = 1 to 10 do printfn "%d" i for j = 10 downto 1 do printfn "%d" j
The while loop
let aa = [|0 .. 6|] let mutable i = 0 while i < (Array.length aa) do printfn "%d" (Array.get aa i) i <- i + 1
The unit type
Functions which take no arguments and/or return no values are said to take and return the type unit. This can be seen as being analogous to void in C#.
The double backtick “ in identifiers
As per Identifiers and Keywords. We can use the double backtick “ to enclose identifier that might be a language keyword, for example
let ``private`` = 1
is valid even though private is a keyword. We can also have spaces in identifiers such as
let ``add two numbers`` () = // function definition