Basics
Comments Block comments are placed between (* This is block comment *) // And this is line comment XML doc comments come after /// The `let` keyword defines an (immutable) value let result = 1 + 1 = 2 

Strings F# /// Create a string using string concatenation let hello = "Hello" + " World" Use verbatim strings preceded by let verbatimXml = @"<book title=""Paradise Lost"">" We don't even have to escape let tripleXml = """<book title="Paradise Lost">""" Backslash strings indent string contents by stripping leading spaces. let poem = "The lesser world was daubed\n\ By a colorist of modest skill\n\ A master limned you in the finest inks\n\ And with a freshcut quill." 

Basic Types and Literals Most numeric types have associated suffixes, e.g., let b, i, l = 86uy, 86, 86L // [fsi:val b : byte = 86uy] // [fsi:val i : int = 86] // [fsi:val l : int64 = 86L] Other common examples are let s, f, d, bi = 4.14F, 4.14, 0.7833M, 9999I // [fsi:val s : float32 = 4.14f] // [fsi:val f : float = 4.14] // [fsi:val d : decimal = 0.7833M] // [fsi:val bi : System.Numerics.BigInteger = 9999] See Literals (MSDN) for complete reference. 

Tuples and Records A tuple is a grouping of unnamed but ordered values, possibly of different types: // Tuple construction let x = (1, "Hello") // Triple let y = ("one", "two", "three") // Tuple deconstruction / pattern let (a', b') = x The first and second elements of a tuple can be obtained using let c' = fst (1, 2) let d' = snd (1, 2) let print' tuple = match tuple with  (a, b) > printfn "Pair %A %A" a b Records represent simple aggregates of named values, optionally with members: // Declare a record type type Person = { Name : string; Age : int } // Create a value via record expression let paul = { Name = "Paul"; Age = 28 } // 'Copy and update' record expression let paulsTwin = { paul with Name = "Jim" } Records can be augmented with properties and methods: type Person with member x.Info = (x.Name, x.Age) Records are essentially sealed classes with extra topping: default immutability, structural equality, and pattern matching support. let isPaul person = match person with  { Name = "Paul" } > true  _ > false 

Discriminated Unions Discriminated unions (DU) provide support for values that can be one of a number of named cases, each possibly with different values and types. type Tree<'T> =  Node of Tree<'T> * 'T * Tree<'T>  Leaf let rec depth = function  Node(l, _, r) > 1 + max (depth l) (depth r)  Leaf > 0 They allow to wrap a type using Single case union types (Designing with types: Single case union types: type CustomerId = CustomerId of int let custId = CustomerId 1 // deconstruct in the param let printCustomerId (CustomerId customerIdInt) = printfn "The CustomerId is %i" customerIdInt // or deconstruct explicitly through let statement let printCustomerId2 custId = let (CustomerId customerIdInt) = custId // deconstruct here printfn "The CustomerId is %i" customerIdInt F# Core has a few builtin discriminated unions for error handling, e.g., Option and Choice. let optionPatternMatch input = match input with  Some i > printfn "input is an int=%d" i  None > printfn "input is missing" Singlecase discriminated unions are often used to create typesafe abstractions with pattern matching support: type OrderId = Order of string // Create a DU value let orderId = Order "12" // Use pattern matching to deconstruct singlecase DU let (Order id) = orderId 

Exceptions Throw an exception using a builtin keyword:
let divideFailwith x y = if y = 0 then failwith "Divisor cannot be zero." else x / y Exception handling is done via let divide x y = try Some (x / y) with :? System.DivideByZeroException > printfn "Division by zero!" None The exception InnerError of string exception OuterError of string let handleErrors x y = try try if x = y then raise (InnerError("inner")) else raise (OuterError("outer")) with InnerError(str) > printfn "Error1 %s" str finally printfn "Always print this." Raising an exception is done using the exception MyError of string raise (MyError "my error") 
Functions
Definition The let negate x = x * 1 let square x = x * x let print x = printfn "The number is: %d" x let squareNegateThenPrint x = print (negate (square x)) Infix operator declaration: let (**) x n = Math.Pow(x, n) 

Pipe and composition operators Pipe operator let ``square, negate, then print`` x = x > square > negate > print This operator is essential in assisting the F# type checker by providing type information before use: let sumOfLengths (xs : string []) = xs > Array.map (fun s > s.Length) > Array.sum Composition operator let squareNegateThenPrint' = square >> negate >> print 

Recursive functions The let rec fact x = if x < 1 then 1 else x * fact (x  1) Mutually recursive functions (those functions which call each other) are indicated by let rec even x = if x = 0 then true else odd (x  1) and odd x = if x = 1 then true else even (x  1) 
Collections
Lists A list is an immutable collection of elements of the same type. // Lists use square brackets and `;` delimiter let list1 = [ "a"; "b" ] // :: (cons operator) is prepending let list2 = "c" :: list1 // @ is concat let list3 = list1 @ list2 // Recursion on list using (::) operator let rec sum list = match list with  [] > 0  x :: xs > x + sum xs 

Arrays Arrays are fixedsize, zerobased, mutable collections of consecutive data elements. // Arrays use square brackets with bar let array1 = [ "a"; "b" ] // Indexed access using dot let first = array1.[0] 

Sequences A sequence is a logical series of elements of the same type. Individual sequence elements are computed only as required, so a sequence can provide better performance than a list in situations in which not all the elements are used. // Sequences can use yield and contain subsequences let seq1 = seq { // "yield" adds one element yield 1 yield 2 // "yield!" adds a whole subsequence yield! [5..10] } 

Higherorder functions on collections The same list
let xs = [ 1..2..9 ]
let ys = [ for i in 0..4 > 2 * i + 1 ]
let zs = List.init 5 (fun i > 2 * i + 1) Lists and arrays have comprehensive sets of higherorder functions for manipulation.
let xs' = Array.fold (fun str n > sprintf "%s,%i" str n) "" [ 0..9 ]
let last xs = List.reduce (fun acc x > x) xs
let ys' = Array.map (fun x > x * x) [ 0..9 ]
let _ = List.iter (printfn "%i") [ 0..9 ] All these operations are also available for sequences. The added benefits of sequences are laziness and uniform treatment of all collections implementing let zs' = seq { for i in 0..9 do printfn "Adding %d" i yield i } 
Pattern Matching
Pattern Matching Pattern matching is often facilitated through let rec fib n = match n with  0 > 0  1 > 1  _ > fib (n  1) + fib (n  2) In order to match sophisticated inputs, one can use let sign x = match x with  0 > 0  x when x < 0 > 1  x > 1 Pattern matching can be done directly on arguments: let fst' (x, _) = x or implicitly via /// Similar to `fib`; using `function` for pattern matching let rec fib' = function  0 > 0  1 > 1  n > fib' (n  1) + fib' (n  2) For more complete reference visit Pattern Matching (MSDN). 

Active Patterns Complete active patterns: let (EvenOdd) i = if i % 2 = 0 then Even else Odd let testNumber i = match i with  Even > printfn "%d is even" i  Odd > printfn "%d is odd" i Parameterized active patterns: let (DivisibleBy_) by n = if n % by = 0 then Some DivisibleBy else None let fizzBuzz = function  DivisibleBy 3 & DivisibleBy 5 > "FizzBuzz"  DivisibleBy 3 > "Fizz"  DivisibleBy 5 > "Buzz"  i > string i Partial active patterns share the syntax of parameterized patterns but their active recognizers accept only one argument. 
Scripting
Compiler Directives Load another F# source file into FSI. #load "../lib/StringParsing.fs" Reference a .NET assembly ( #r "../lib/FSharp.Markdown.dll" Include a directory in assembly search paths. #I "../lib" #r "FSharp.Markdown.dll" Other important directives are conditional execution in FSI ( #if INTERACTIVE let path = __SOURCE_DIRECTORY__ + "../lib" #else let path = "../../../lib" #endif 