Lists

module ListsOfIntegers =
/// A list of the numbers from 0 to 99
let sampleNumbers = [ 0 .. 99 ]
/// A list of all tuples containing all the numbers from 0 to 99 and their squares
let sampleTableOfSquares = [ for i in 0 .. 99 -> (i, i*i) ]
// The next line prints a result using %A for generic printing
printfn "The numbers from 0 to 99 are:\n%A" sampleNumbers
// The next line prints a list that includes tuples, using %A for generic printing
printfn "The table of squares from 0 to 99 is:\n%A" sampleTableOfSquares

Basic Functions

/// This first module some basic function definitions in F#.
module SomeBasicFunctionsAndTypeInference =
/// This shows how to use 'let' to define a function that accepts an integer
/// as an argument and returns an integer. The type of the argument is inferred to
/// be an integer.
let sampleFunction1 x = x*x + 3
// The next line applies the function and gives the result a name using 'let'. The result type
// is inferred from the type of the function.
let sampleResult1 = sampleFunction1 4573
// The next line prints the result of applying the function
printfn "The result of squaring the integer 4573 and adding 3 is %d" sampleResult1
/// Where needed, you can annotate the type of a parameter name using "(argument:type)",
/// as shown in the sample below.
let sampleFunction2 (x:int) = 2*x*x - x/5 + 3
// Again the next line applies the function and gives the result a name using 'let'.
let sampleResult2 = sampleFunction2 (7 + 4)
printfn "The result of applying the 1st sample function to (7 + 4) is %d" sampleResult2
/// This shows a similar function that accepts and returns floating-point numbers.
/// In this example, the argument and return types of the function are inferred to
/// have type 'float' (also called 'double') based on the implementation code.
let sampleFunction3 x =
if x < 100.0 then
2.0*x*x - x/5.0 + 3.0
else
2.0*x*x + x/5.0 - 37.0
/// The result of applying 'sampleFunction3' over double-precision floating point numbers
let sampleResult3 = sampleFunction3 (6.5 + 4.5)
printfn "The result of applying the 2nd sample function to (6.5 + 4.5) is %f" sampleResult3

Tuples

/// This sample defines and prints some basic tuple values in F#.
module SomeBasicTuples =
/// A simple tuple of integers
let sampleTuple1 = (1, 2, 3)
/// A function that swaps the order of two values in a tuple. If you hover
/// the mouse over the function you will see its inferred type is generic.
let swapElementsOfTuple (a, b) = (b, a)
printfn "The result of swapping (1, 2) is %A" (swapElementsOfTuple (1,2))
/// A simple tuple of an integer, a string and a double-precision floating point number
let sampleTuple2 = (1, "fred", 3.1415)
printfn "The first sample tuple is %A" sampleTuple1
printfn "The second sample tuple is %A" sampleTuple2

String Values

/// This sample defines and prints some basic string values in F#.
module SomeStringValues =
/// A simple string
let sampleString1 = "Hello"
/// A second simple string
let sampleString2 = "world"
/// A third string, using a verbatim string literal
let sampleString3 = @"c:\Program Files\"
/// A fourth string, using a triple-quote string literal
let sampleString4 = """He said "hello world" after you did"""
/// "Hello world" computed using string concatenation
let resultString1 = sampleString1 + " " + sampleString2
printfn "The first result string is '%s'" resultString1
/// "Hello world" computed using a .NET library function
let resultString2 = System.String.Join(" ",[| sampleString1; sampleString2 |])
// Try re-typing the above line to see intellisense in action
// Note, ctrl-J on (partial) identifiers re-activates it
printfn "The second result string is '%s'" resultString2
/// A string formed by taking the first 7 characters of one of the result strings
let resultString3 = resultString1.[0..6]
printfn "The third result string is '%s'" resultString1

Basic Lists

/// This sample shows some more basic list values in F# and how to
/// processes lists using functions such as 'map' and pipelining
module WorkingWithLists =
/// The empty list
let sampleList1 = [ ]
/// A list with 3 integers
let sampleList2 = [ 1; 2; 3 ]
/// A sample list, containing numbers from 1 to 1000
let sampleList3 = [ 1 .. 1000 ]
/// Create another list, containing the days which are Monday in the current year
let sampleList4 =
[ for month in 1 .. 12 do
for day in 1 .. System.DateTime.DaysInMonth(2011, month) do
yield System.DateTime(2011, month, day) ]
/// Create a list containing the tuples which are the coordinates of the black squares on
/// a chess board.
let sampleList5 =
[ for i in 0 .. 7 do
for j in 0 .. 7 do
if (i+j) % 2 = 1 then
yield (i, j) ]
/// Sum of a list
let sumOfSampleList3 = List.sum sampleList3
/// A new list with the squares of the numbers from 10 to 20. The function
/// is defined using the pipeline operator.
let resultList2 =
sampleList3 |> List.map (fun x -> x*x)
/// A function that computes the sum of the squares of the numbers divisible by 3.
let sumOfSquaresUpTo n =
sampleList3
|> List.filter (fun x -> x % 3 = 0)
|> List.sumBy (fun x -> x * x)
// Many more functions are in the 'List' module. You can also use functions in
// the 'Seq' module to process lists.

Dictionaries

/// This sample defines and use some dictionary and lookup table values in F#.
module SomeDictionaryValues =
/// The 'open' declaration is used to open a namespace.
/// They are usually placed at the start of a file or module.
open System.Collections.Generic
/// This creates an immutable dictionary with integer keys and string values.
/// Lookup is based on hashing the keys, which are the first elements of the tuples.
let sampleLookupTable1 = dict [ (1, "ElementOne"); (2, "ElementTwo") ]
/// This creates a much large immutable dictionary with integer keys and string values.
let sampleLookupTable2 = dict [ for i in 0 .. 10000 -> (i, "Element" + string i) ]
/// This looks up one entry in the dictionary. Its result is "ElementOne".
let sampleLookupResult1 = sampleLookupTable1.[1]
/// This looks up one entry in the dictionary. Its result is "Element100".
let sampleLookupResult2 = sampleLookupTable2.[100]
/// This function creates a mutable dictionary with integer keys and string values
let createAndPopulateDictionary() =
let sampleDictionary = Dictionary<int,string>()
for key,value in [ (1, "One"); (2, "Two") ] do
sampleDictionary.Add (key,value)
sampleDictionary
/// A mutable dictionary created using createAndPopulateDictionary.
let sampleLookupTable3 = createAndPopulateDictionary()
/// This looks up one entry in the dictionary
let sampleLookupResult3 = sampleLookupTable2.[2]
/// This creates an immutable map, based on a balanced binary tree, with integer keys and string values.
/// Keys are compared using an ordering.
let sampleLookupTable4 = Map.ofList [ for i in 0 .. 1000 -> (i, string (i*i)) ]
/// This looks up one entry in the dictionary
let sampleLookupResult4 = sampleLookupTable4.[465]

OOP / Classes

/// This sample shows how to define a simple class type.
module DefiningClasses =
/// A sample class defining a 2-dimensional vector type. The constructor
/// for the type takes two arguments: dx and dy, both of type 'float'. This
/// is the type of double-precision floating-point numbers and is a synonym
/// for 'double'.
type SampleObject(dx:float, dy:float) =
/// The length of the vector, computed when the object is constructed
let length = sqrt (dx*dx + dy*dy)
/// The first parameter of the object
member v.DX = dx
/// The second parameter of the object
member v.DY = dy
/// The length of the object
member v.Length = length
// Return a new the vector where both parameters are scaled by a constant
member v.Scale(k) = SampleObject(k*dx, k*dy)
/// An instance of the SampleObject class
let sampleObject1 = SampleObject(3.0, 4.0)
// Call a method on the sample object which returns a new object modifies its state.
let sampleObject2 = sampleObject1.Scale(10.0)
printfn "The length of sampleObject2 is %f" sampleObject2.Length
printfn "The length of sampleObject2 is %f" sampleObject2.Length

Parameter Lists

/// This sample shows some parameter lists in F#.
module ParameterLists =
// Parameters supplied to functions and methods are, in general, patterns separated by spaces.
//
// Methods usually use the tupled form of passing arguments. This achieves a clearer result from
// other .NET languages.
//
// The curried form is most often used with functions created by using let bindings.
//
// Tupled form:
// member this.SomeMethod(param1, param2) = ...
//
// Curried form:
// let function1 param1 param2 = ...
/// This is an example of a function taking three arguments in curried form
let addUpTheNumbers x y z = x + y + z
printfn "The result of adding up the numbers is '%d'" (addUpTheNumbers 9 32 12)
/// This is an example of a function taking three arguments in tupled form.
let addUpTheNumbersInTheTuple (x, y, z) = x + y + z
printfn "The result of adding up the numbers is '%d'" (addUpTheNumbersInTheTuple (9, 32, 12))
type Slice = Slice of int * int * string
/// You can use other patterns within arguments. This sample shows how to match a single case
/// union type using the name of the tag for the union case.
let getSlice (Slice(p0, p1, text)) =
printfn "Data begins at %d and ends at %d in string %s" p0 p1 text
text.[p0..p1]
let substring = getSlice (Slice(0, 4, "Et tu, Brute?"))
printfn "Substring: %s" substring
/// Arguments for methods can be specified by position in a comma-separated argument list, or they can be passed
/// to a method explicitly by providing the name, followed by an equal sign and the value to be passed in.
/// If specified by providing the name, they can appear in a different order from that used in the declaration.
///
/// Named arguments are allowed only for methods, not for let-bound functions, function values, or lambda expressions.
type SpeedingTicket(speed: int, limit: int) =
member this.GetSpeedOver() = speed - limit
let calculateFine (ticket : SpeedingTicket) =
let delta = ticket.GetSpeedOver()
if delta < 20 then 50.0 else 100.0
let ticket1 = SpeedingTicket(limit = 55, speed = 70)
printfn "The speeding fine is %f" (calculateFine ticket1)
/// You can specify an optional parameter for a method by using a question mark in front of the parameter name.
/// Optional parameters are interpreted as the F# option type, so you can query them in the regular way that
/// option types are queried, by using a match expression with Some and None. Optional parameters are
/// permitted only on members, not on functions created by using let bindings.
type DuplexType =
| Full
| Half
type Connection(?rate0 : int, ?duplex0 : DuplexType, ?parity0 : bool) =
let duplex = defaultArg duplex0 Full
let parity = defaultArg parity0 false
let rate = defaultArg rate0 (match duplex with Full -> 9600 | Half -> 4800)
do printfn "Baud Rate: %d Duplex: %A Parity: %b" rate duplex parity
let conn1 = Connection(duplex0 = Full)
let conn2 = Connection(duplex0 = Half)
let conn3 = Connection(300, Half, true)

Generics

/// This sample shows how to define a generic class type.
module DefiningGenericClass =
/// A class which contains one item of mutable state and which implements the given interface.
type HistoricalStateTracker<'T>(initialElement: 'T) =
/// The internal state of the class, recording the historical states in reverse order
let mutable historicalStates = [ initialElement ]
/// Add a new element to the list of states
member x.UpdateState newState =
historicalStates <- newState :: historicalStates
/// Get the entire list of historical states
member x.History = historicalStates
/// Get the latest state
member x.CurrentState = historicalStates.Head
/// A sample instance of the HistoricalStateTracker class, stogin integers
let sampleStateTracker = HistoricalStateTracker 10
// Add a state
sampleStateTracker.UpdateState 17
// Get the history
sampleStateTracker.History

Recursion

/// This sample shows how to define recursive functions.
module DefiningRecursiveFunctions =
/// Compute the factorial of an integer. The function is recursive and is thus defined using
/// 'let rec'.
let rec factorial n = if n = 0 then 1 else n * factorial (n-1)
/// Compute the highest-common-factor of two integers. The function is recursive and is thus defined using
/// 'let rec'. The recursive calls are tailcalls and the function is turned into a loop.
/// Also, note that in F#, a function may take two arguments separated by spaces. This is called
/// 'currying'.
let rec highestCommonFactor a b =
if a=0 then b
elif a<b then highestCommonFactor a (b-a)
else highestCommonFactor (a-b) b
/// Compute the sum of a list of integers using a recursive function. The function is recursive and is thus defined using
/// 'let rec'.
let rec sumList xs =
match xs with
| [] -> 0
| y::ys -> y + sumList ys
/// Sometimes functions need to be made 'tail recursive'. This can mean using a helper
/// function which carries an accumulator which builds up the result. This function
/// shows an example of such a helper function.
let rec private sumListTailRecursiveHelper accumulator xs =
match xs with
| [] -> accumulator
| y::ys -> sumListTailRecursiveHelper (accumulator+y) ys
/// This function calls the helper function to process the elements of the list in a
/// tail-recursive way.
let sumListTailRecursive xs = sumListTailRecursiveHelper 0 xs

Interfaces

/// This sample shows how to define an interface type and a class that implements it.
module DefiningClassesAndInterfaces =
/// A sample interface type with two methods.
type IPeekPoke =
/// A method on the interface type. It takes no arguments. The type 'unit' is the F# name for both
/// 'no arguments' and 'no results', called 'void' in languages such as C#.
abstract Peek: unit -> int
/// A second method on the interface type. It takes one argument and returns no result.
abstract Poke: int -> unit
/// A class which contains one item of mutable state and which implements the given interface.
type ClassImplementingPeekPoke(initialState:int) =
/// The internal state of the ClassImplementingPeekPoke
let mutable state = initialState
// Implement the IPeekPoke interface
interface IPeekPoke with
member x.Poke n = state <- state + n
member x.Peek() = state
/// Has the ClassImplementingPeekPoke been poked?
member x.HasBeenPoked = (state <> 0)
/// A sample instance of the ClassImplementingPeekPoke class, viewed through the IPeekPoke interface.
let sampleObject = ClassImplementingPeekPoke(12) :> IPeekPoke
// Call a method on the sample widget which modifies its state.
sampleObject.Poke(4)
// Get the result of calling a method on the sample widget.
let peekResult = sampleObject.Peek()
// A list of two objects, each implementing the interface, but sharing state.
// The implementations each use an F# object expression, which is a convenient
// way of implementing objects without needing to write a new class.
let alternativeImplementations() =
// Use a F# reference cell as the shared state
let sharedState = ref 0
[ { new IPeekPoke with
member x.Peek() = !sharedState / 2
member x.Poke n = sharedState := n }
{ new IPeekPoke with
member x.Peek() = !sharedState * 2
member x.Poke n = sharedState := n } ]

.NET Libraries

/// This sample shows working with the .NET times for decimals and dates.
module WorkingWithDotNetLibraryTypes =
open System
/// The current time
let sampleTime = DateTime.Now
/// A list with 2 dates - the start and end of the year 2011
let sampleListOfDates = [ DateTime(2011,1,1); DateTime(2011,12,31) ]
/// Create another list, containing the days which are Saturday or Sunday in the current year
let sampleListOfDates4 =
[ for month in 1 .. 12 do
let thisYear = DateTime.Now.Year
for day in 1 .. DateTime.DaysInMonth(thisYear, month) do
let date = DateTime(year=thisYear, month=month, day=day)
match date.DayOfWeek with
| DayOfWeek.Saturday
| DayOfWeek.Sunday -> yield date
| _ -> () ]
/// Decimal literals use the 'M' suffix
let sampleDecimalConstant = 103.62M
/// A function to increment a decimal
let incrementMoney (x:System.Decimal) = x + 1.0M
/// Some data representing account values
let accounts = [ 23.6M; 101.62M; 13.62M ]
/// The result of adding up some decimal constants
let addingUpDecimalNumbers = accounts |> List.map incrementMoney |> List.sum
// Many more types, properties and methods are in the 'Sys

.NET Regular Expressions

/// This sample shows how to use the .NET regular expression libraries from F#
module WorkingWithRegularExpressions =
open System.Text.RegularExpressions
let names = ["Mr. Henry Hunt"; "Ms. Sara Samuels"; "Abraham Adams"; "Ms. Nicole Norris"]
/// This example shows how to check if a string matches a regular expression.
/// The regular expression pattern matches any occurrence of "Mr ", "Mr. ", "Mrs ",
/// "Mrs. ", "Miss ", "Ms " or "Ms. "
let namesWithTitle =
names |> List.filter (fun name -> Regex.IsMatch(name, @"(Mr\.? |Mrs\.? |Miss |Ms\.? )"))
/// This example shows how to remove all titles by replacing with the empty string.
let namesWithTitlesRemoved =
names |> List.map (fun name -> Regex.Replace(name, @"(Mr\.? |Mrs\.? |Miss |Ms\.? )", ""))
/// A function to identify duplicate words in some input text.
/// \b - Start at a word boundary.
/// (\w+) - Match one or more word characters. Together, they form a group that can be referred to as \1.
/// \s - Match a white-space character.
/// \1 - Match the substring that is equal to the group named \1.
/// \b - Match a word boundary.
let identifyDuplicateWords input =
for m in Regex.Matches(input, @"\b(\w+?)\s\1\b", RegexOptions.IgnoreCase) do
printfn "\"%s\" duplicates '%s' at position %d" m.Value m.Groups.[1].Value m.Index
/// Run the sample
identifyDuplicateWords "This this is a nice day. What about this? This tastes good. I saw a a dog."
// More information on using regular expressions with F# is available on MSDN.

Events

/// This sample shows how you can react to events in F# code.
module Events =
open System.Drawing
open System.Windows.Forms
/// Create a form
let form = new Form(Text = "Sample Form For Events", TopMost=true, Size=Size(300,300), Visible=true)
let button1 = new Button(Text = "Press Button 1", Location=Point(100,100), AutoSize=true)
let button2 = new Button(Text = "Launch", Location=Point(100,160), AutoSize=true)
let text = new Label (Text = "This form is a part of the 'Events' sample for showing how F# programs can react to events such as mouse clicks",
Location=Point(20,50), Size=Size(260,40))
form.Controls.Add button1
form.Controls.Add button2
form.Controls.Add text
// This shows how to react to an event using a standard synchronous handler. You can also use
// AddHandler and RemoveHandler to detach specific handler objects.
button1.MouseClick.Add (fun args ->
text.Text <- sprintf "Button #1 was clicked. The mouse position (%d, %d)" args.X args.Y
)
// This shows how to react to an event using a pipeline of handlers.
form.MouseMove
|> Event.filter (fun args -> args.X < 10 && args.Y < 10)
|> Event.add (fun args ->
text.Text <- sprintf "The mouse moved over the secret area at position (%d, %d)" args.X args.Y
)
// This shows how to react to an event using an asynchronous handler that starts a co-routine. See the
// later samples for more information on asynchronous programming.
button2.MouseClick.Add (fun args ->
async {
for i in 5.0 .. -0.1 .. 0.0 do
text.Text <- sprintf "Countdown: %0.2f" i
do! Async.Sleep 100
text.Text <- "Blast off!"
} |> Async.StartImmediate)

Lightweight Asynchronous Agent

/// This sample shows how you to create a lightweight asynchronous agent in F# code.
module Agents =
/// This is a common type alias used for the F# mailbox processor type
type Agent<'T> = MailboxProcessor<'T>
/// A simple agent that reacts to messsages, which are strings
let agent1 =
Agent.Start (fun inbox -> async {
while true do
let! message = inbox.Receive()
printfn "[Agents] Agent #1 received message <<<%s>>>" message
})
// Send 10 messages to the agent
for i in 1 .. 10 do
agent1.Post (sprintf "message %d to agent" i)
/// A message type used by the second agent
type Message =
| Message1 of int
| Message2 of AsyncReplyChannel<int>
/// The second agent. The body is a series of asynchronous recursive functions.
let agent2 =
Agent.Start (fun inbox ->
let rec state1 total =
async { printfn "[Agents] now in state #1, total = %d" total
let! message = inbox.Receive()
match message with
| Message1 n ->
// Increment and go to state #2
return! state2 (total + n)
| Message2 reply ->
// Reply to the message and stay in state #1
reply.Reply total;
return! state1 total }
and state2 total =
async { printfn "[Agents] now in state #2, total = %d" total
let! message = inbox.Receive()
match message with
| Message1 n ->
// Increment and go to state #1
return! state1 (total + n)
| Message2 reply ->
// Reply to the message and stay in state #2
reply.Reply total;
return! state2 total }
// Start in state one
state1 0
)
for i in 1 .. 10 do
agent2.Post (Message1 i)
let total = agent2.PostAndReply Message2

Database Access

/// This sample indicates how to access a database from F#.
module DatabaseAccess =
// The easiest way to access a SQL database from F# is to use F# type providers. To do this in
// a project, add a reference to System.Data, System.Data.Linq, FSharp.Data.TypeProviders.dll.
// You can use Server Explorer to build your ConnectionString.
(*
#if INTERACTIVE
#r "System.Data"
#r "System.Data.Linq"
#r "FSharp.Data.TypeProviders"
#endif
open Microsoft.FSharp.Data.TypeProviders
type SqlConnection = SqlDataConnection<ConnectionString = @"Data Source=.\sqlexpress;Initial Catalog=tempdb;Integrated Security=True">
let db = SqlConnection.GetDataContext()
let table =
query { for r in db.Table do
select r }
*)
// You can also use SqlEntityConnection instead of SqlDataConnection, which accesses the database using Entity Framework.
//
// Alternatively, use the ADO.NET library to access database connections in a dynamically typed way.
let placeHolder = 1

OData Access

module ODataAccess =
// The easiest way to access an OData service from F# is to use F# type providers. To do this in
// a project, add a reference to System.Data, System.Data.Linq, FSharp.Data.TypeProviders.dll.
//
// For more about OData see www.odata.org. You can use a search engine to find suitable service URLs.
// One good source of OData sources is the Azure Data Market.
(*
#if INTERACTIVE
#r "System.Data.Services.Client"
#r "FSharp.Data.TypeProviders"
#endif
// open System.Data.Services.Client
// open Microsoft.FSharp.Data.TypeProviders
// Consume demographics population and income OData service from Azure Marketplace. For more information, Please go to https://datamarket.azure.com/dataset/c7154924-7cab-47ac-97fb-7671376ff656
type Demographics = ODataService<ServiceUri = "https://api.datamarket.azure.com/Esri/KeyUSDemographicsTrial/">
let ctx = Demographics.GetDataContext()
//To sign up for a Azure Marketplace account at https://datamarket.azure.com/account/info
ctx.Credentials <- System.Net.NetworkCredential ("<your liveID>", "<your Azure Marketplace Key>")
let cities =
query { for c in ctx.demog1 do
where (c.StateName = "Washington")
select c }
for c in cities do
printfn "%A - %A" c.GeographyId c.PerCapitaIncome2010.Value
*)
let placeHolder = 1