domain.dot.net team

10.09.08

F# : absolute power corrupts absolutely, but F# removes side-effect corruption so uh.. there goes my analogy0

Filed under: F#, Functional Programming — Damon Wilder Carr @ 12:36 am
Tags: , , , ,

kick it on DotNetKicks.com

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 =
| Num
ofint
| Add
ofExpr * Expr
| Mul
ofExpr * Expr
| Var
ofstring

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
member
x.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

Related Posts

Digg This

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.