Core Language Syntax Examples
Last changed: -83.199.19.152

.
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"