strangelights.com

Main F# Site

Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Search
List all versions List all versions
Core Language Syntax Examples
.
Summary

Integers

  let i1 = 12
  let i2 = 23 + 23
  let i3 = 0x80d099FE
  let a1 = 0x00FE &&& 0x1211   // and
  let a2 = 0x00FE ||| 0x1211   // or
  let a3 = 0x00FE ^^^ 0x1211   // xor
  let a4 = ~~~ a3              // not
  let a5 = 0x1234 <<< 3        // left shift
  let a6 = 0x1234 >>> 2        // right shift


  do  printf "%08x %08x %08x\n" a1 a2 a3
  do  printf "%08x %08x %08x\n" a4 a5 a6

Floats (double-precision = System.Double)

Compatibility note:

  let r1 = 2.0 * 3.1415 + 1.0
  let r2 = float 123
  do  printf "%f %f\n" r1 r2


  let r1_caml = 2.0 *. 3.1415 +. 1.0

Strings ( = System.String)

  let strA = "SySt3M H4Ck4Rz"
  let strB = "Network Police"


  // MLLib.String functions:
  let lenA = String.length strA             // length 
  let strC = strA ^ " out fox " ^ strB      // concatenation
  let strD = String.sub strA 7 7            // substring


  // System.String static/instance methods
  let lenD = strD.Length       // property
  let strE = strD.ToUpper()    // instance method

Find documentation online by searching for:

Tuples

  let tupA = 1,false
  let tupB = 1,true,"three"


  let fst (a,b) = a
  let snd (a,b) = b


  let rw1'2 f (a,b) = f a,b
  let rw2'2 f (a,b) = a,f b


  let tupA2 = rw2'2 not tupA

Records (immutable)

  type stat =
      {count : int;
       sum   : int;
       panic : bool;
      }


  let stat0 = {count=0; sum=0; panic=false}
  let noPanic stat = {stat with panic=false}
  let monitor stat n =
    if n=999 then
      {stat with panic=true}
    else
      {stat with count = stat.count + 1; sum = stat.sum + n}


  // These records are labeled tuples.
  // You can build them directly or from another record by replacing selected fields.


  let dataset = [| 1;2;3;4;5;6;7;8;9;10 |] : int array


  // Functional style - folds state through
  let stat = Array.fold_left monitor stat0 dataset

Records (mutable)

  type mstat =
      {mutable mcount : int;
       mutable msum   : int;
       mutable mpanic : bool;
      }


  let createStat0 () = {mcount=0; msum=0; mpanic=false}
  let doNoPanic mstat = mstat.mpanic <- false
  let doMonitor mstat n =
    if n=999 then
      mstat.mpanic <- true
    else (
      mstat.mcount <- mstat.mcount + 1;
      mstat.msum   <- mstat.msum + n
    )


  // The assignment operator is <-
  // Note: assignment expression sequence - seperated by SEMI colons
  // Note: brackets required for precedence reasons


  // Imperative style - iterates and mutates state
  let mstat = createStat0 ()
  do
    for i = 0 to Array.length dataset - 1 do
      printf "Monitoring index = %d\n" i;
      doMonitor mstat dataset.(i)
    done  


Lists (functional programming immutable singly-linked lists)

  let xsA = []                 // empty list
  let xsB = 1 :: xsA           // cons
  let xsC = [1;2;3;4;5] @ xsB  // append


  let nxsA   = List.length xsA
  let ysC    = List.map (fun i -> i*10) xsC
  let sumXsC = List.fold_left (fun sum x -> sum+x) 0 xsC
  let sumYsC = List.fold_left (fun sum x -> sum+x) 0 ysC
  let xsD    = List.filter (fun x -> x mod 2 = 1) xsC


  let rec interleave xs ys =
    match xs,ys with
        x::xs,y::ys -> x::y::interleave xs ys
      | []   ,ys    -> ys
      | xs   ,[]    -> xs


  let xysC = interleave xsC ysC        

Arrays

F# has generic (polymorphic) arrays. In .NET 2.0, there is a generic array type (thanks don!). F# arrays are .NET arrays.

  let arrA = [| 0;2;4;6;8 |]                      // array expressions
  let arrB = Array.init 5 (fun i -> i*2)          // initialisation calls
  let arrC = Array.append [|0;2;4|]  [|6;8|]      // append


  // MLLib.Array.* functions are ML-like functions
  let lenArrA = Array.length arrA
  let eltArrA = arrA.(0)
  let sumArr arr = Array.fold_left (fun sum n -> sum + n) 0 arr


  // .NET instance/static members usable
  // Note, use of instance members require the type to be known.
  let sumArr2 (arr : 'a array) =
    let mutable sum = 0 in
    for i = 0 to arr.Length - 1 do
      sum <- sum + arr.(i)
    done;
    sum


  // Array type can be written in ML or .NET style
  let arrX = [| "Alpha"; "Beta" |] : string array
  let arrY = [| "Alpha"; "Beta" |] : string[]


Datatypes

  type colour =
    | Red
    | Green
    | Blue
    | RGB   of float * float * float (* floats in [0,1] *)
    | Alpha of float * colour        (* float  in [0,1] *)

Functions over datatypes by pattern matching

  let rec redPart c = match c with
    | Red         -> 255.0
    | Green       -> 0.0
    | Blue        -> 0.0
    | RGB (r,g,b) -> r
    | Alpha (a,c) -> a * redPart c

Build a .NET System.Drawing.Color value

  open System.Drawing
  let int255 x = int_of_float (x * 255.0)


  let rec color c = match c with
    | Red         -> Color.Red
    | Green       -> Color.Green
    | Blue        -> Color.Blue
    | RGB (r,g,b) -> Color.FromArgb(int255 r,int255 g,int255 b)
    | Alpha (a,c) -> Color.FromArgb(int255 a,color c)

Function values

There are two ways to create lambda expressions.

  "fun ..."            when there are no alternatives.
  "function ... | ..." when there are.

Note, precedence differs. You will mostly want to use "fun" for anonymous lambda expr.

  // fun <pattern> -> <expr>
  let inc = fun x -> x + 1
  let incList = List.map inc
  let xs = incList [1;2;3]


  // function <pattern> -> <expr> | <pattern> -> <expr> | ...
  let rotate = function
    | []    -> []
    | x::xs -> xs @ [x]


  // sumList - versionA
  let rec sumListA xs = match xs with
    | [] -> 0
    | x::xs -> x + sumListA xs


  let sumListB xs = List.fold_left (fun sum x -> sum + x) 0 xs
  let sumListC xs = List.fold_left (+) 0 xs


  // NB: bracket infix op in order to use it as nonfix function
  // eg: (+) (-) (&&&) but beware of "comment issues" for * !!


.NET types

  // The .NET types are also available.


  open System.Net
  let newsIPE   = Dns.GetHostByName("news.bbc.co.uk") // Static method
  let newsAddrs = newsIPE.AddressList                 // get property


  // constructors - overload resolved statically
  let ipA  = new IPAddress( 0xd43ae235L )               // L suffix for int64 literal
  let ipB  = new IPAddress( [|212uy;58uy;226uy;53uy|] ) // uy suffix for byte literal
  let ipLB = new IPAddress( 0x0100007fL )


  let qA   = IPAddress.IsLoopback(ipA)   // static method "type.method(args)"
  let qLB  = IPAddress.IsLoopback(ipLB)


  let absA = ipA.GetAddressBytes()       // instance method  


  let addr = ipA.Address                 // get property
  do  ipB.Address <- 0x0100007fL         // set property


  let loopbackIP = IPAddress.Loopback    // static field
  let anyIP      = IPAddress.Any 


Misc

  let parity n =
    match n mod 2 with
      | 0 -> "even"
      | 1 -> "odd"
      | n -> failwith "parity: dead code"
Welcome to F Sharp Wiki, view the HomePage

This site supports the new NoFollow anti-spam initiative.

Recent Topics

Copyright 2005, Robert Pickering (Others where credited) | Terms of Use