….but F# removes side-effect corruption so uh.. there goes my analogy……
Starting from scratch with F#? Click here.
Functional programming is so addictive. It reminds me when I could code with no team, no deadline, no broken processes or cultures to navigate. I do hope this becomes a common option for general development or at least C# continues to borg functional ideas…
For a larger collection of F# samples, see:
http://go.microsoft.com/fwlink/?LinkID=124614
// F# Tutorial File
//
// This file contains sample code to guide you through the
// primitives of the F# language.
//
// Contents:
// – Simple computations
// – Functions on integers
// – Tuples
// – Booleans
// – Strings
// – Lists
// – Arrays
// – More Collections
// – Functions
// – Types: unions
// – Types: records
// – Types: classes
// – Types: interfaces
// – Types: classes with interface implementations
// – Printing
// Turn on the lightweight syntax
#light
// open some standard namespaces
openSystem
// Simple computations
// —————————————————————
// Here are some simple computations. Note how code can be documented
// with ‘///’ comments. Hover over any reference to a variable to
// see its documentation.
/// A very simple constant integer
letint1 = 1
/// A second very simple constant integer
letint2 = 2
/// Add two integers
letint3 = int1 + int2
// Functions on integers
// —————————————————————
/// A function on integers
letf x = 2*x*x – 5*x + 3
/// The result of a simple computation
letresult = f (int3 + 4)
/// Another function on integers
letincrement x = x + 1
/// Compute the factorial of an integer
let rec factorial n =ifn=0then1elsen * factorial (n-1)
/// Compute the highest-common-factor of two integers
let rec hcf a b = // notice: 2 parameters separated by spaces
ifa=0thenb
elif a<bthenhcf a (b-a) // notice: 2 arguments separated by spaces
elsehcf (a-b) b
// note: function arguments are usually space separated
// note: ‘let rec’ defines a recursive function
// Tuples
// —————————————————————
// A simple tuple of integers
letpointA = (1, 2, 3)
// A simple tuple of an integer, a string and a double-precision floating point number
letdataB = (1,“fred”, 3.1415)
/// A function that swaps the order of two values in a tuple
letSwap (a, b) = (b, a)
// Booleans
// —————————————————————
/// A simple boolean value
letboolean1 =true
/// A second simple boolean value
letboolean2 =false
/// Compute a new boolean using ands, ors, and nots
letboolean3 = not boolean1 && (boolean2 ||false)
// Strings
// —————————————————————
/// A simple string
letstringA =“Hello”
/// A second simple string
letstringB =“world”
/// “Hello world” computed using string concatentation
letstringC = stringA +” “+ stringB
/// “Hello world” computed using a .NET library function
letstringD = String.Join(” “,[| stringA; stringB |])
// Try re-typing the above line to see intellisense in action
// Note, ctrl-J on (partial) identifiers re-activates it
// Functional Lists
// —————————————————————
/// The empty list
letlistA = [ ]
/// A list with 3 integers
letlistB = [ 1; 2; 3 ]
/// A list with 3 integers, note :: is the ‘cons’ operation
letlistC = 1 :: [2; 3]
/// Compute the sum of a list of integers using a recursive function
let rec SumList xs =
matchxs with
| [] ->0
| y::ys ->y + SumList ys
/// Sum of a list
letlistD = SumList [1; 2; 3]
/// The list of integers between 1 and 10 inclusive
letoneToTen = [1..10]
/// The squares of the first 10 integers
letsquaresOfOneToTen = [forxin0..10->x*x ]
// Mutable Arrays
// —————————————————————
/// Create an array
letarr = Array.create 4“hello”
arr.[1] <-“world”
arr.[3] <-“don”
/// Compute the length of the array by using an instance method on the array object
letarrLength = arr.Length
// Extract a sub-array using slicing notation
letfront = arr.[0..2]
// More Collections
// —————————————————————
/// A dictionary with integer keys and string values
letlookupTable = dict [ (1,"One"); (2,"Two") ]
letoneString = lookupTable.[1]
// For some other common data structures, see:
// System.Collections.Generic
// Microsoft.FSharp.Collections
// Microsoft.FSharp.Collections.Seq
// Microsoft.FSharp.Collections.Set
// Microsoft.FSharp.Collections.Map
// Functions
// —————————————————————
/// A function that squares its input
letSquare x = x*x
// Map a function across a list of values
letsquares1 = List.map Square [1; 2; 3; 4]
letsquares2 = List.map (funx->x*x) [1; 2; 3; 4]
// Pipelines
letsquares3 = [1; 2; 3; 4] |> List.map (funx->x*x)
letSumOfSquaresUpTo n =
[1..n]
|> List.map Square
|> List.sum
// Types: unions
// —————————————————————
typeExpr =
| Numofint
| AddofExpr * Expr
| Mul ofExpr * Expr
| Varofstring
let rec Evaluate (env:Map<string,int>) exp =
matchexpwith
| Num n->n
| Add (x,y)->Evaluate env x + Evaluate env y
| Mul (x,y)->Evaluate env x * Evaluate env y
| Var id ->env.[id]
letenvA = Map.of_list ["a",1 ;
"b",2 ;
"c",3 ]
letexpT1 = Add(Var“a”,Mul(Num 2,Var“b”))
letresT1 = Evaluate envA expT1
// Types: records
// —————————————————————
typeCard = { Name : string;
Phone : string;
Ok : bool }
letcardA = { Name =“Alf”; Phone =“(206) 555-8257″; Ok =false}
letcardB = { cardA withPhone =“(206) 555-4112″; Ok =true}
letShowCard c =
c.Name +” Phone: “+ c.Phone + (ifnot c.Okthen ” (unchecked)” else “”)
// Types: classes
// —————————————————————
/// A 2-dimensional vector
typeVector2D(dx:float, dy:float) =
// The pre-computed length of the vector
letlength = sqrt(dx*dx + dy*dy)
/// The displacement along the X-axis
memberv.DX = dx
/// The displacement along the Y-axis
memberv.DY = dy
/// The length of the vector
memberv.Length = length
// Re-scale the vector by a constant
memberv.Scale(k) = Vector2D(k*dx, k*dy)
// Types: interfaces
// —————————————————————
typeIPeekPoke =
abstractPeek: unit->int
abstractPoke: int->unit
// Types: classes with interface implementations
// —————————————————————
/// A widget which counts the number of times it is poked
typeWidget(initialState:int) =
/// The internal state of the Widget
let mutablestate = initialState
// Implement the IPeekPoke interface
interfaceIPeekPoke with
memberx.Poke(n) = state <- state + n
memberx.Peek() = state
/// Has the Widget been poked?
memberx.HasBeenPoked = (state <> 0)
letwidget = Widget(12) :> IPeekPoke
widget.Poke(4)
letpeekResult = widget.Peek()
// Printing
// —————————————————————
// Print an integer
printfn “peekResult = %d”peekResult
// Print a result using %A for generic printing
printfn “listC = %A”listC



