F# Cheat Sheet
F# Cheat Sheet 2. Strings Other conversion functions:
This sheet glances over some of the float float32 int int16
common syntax of the F# language. It In F# Code the type string is equivalent
is designed to be kept close for those to [Link] 4 Tuples
times when you need to jog your let s = "This is a string"
memory on something like loops or Construction
let hello = "Hello"+" World" let x = (1,"Hello")
object expressions. Everything is
designed to be used with the #light Preserve all characters Deconstruction
syntax directive. If you type any of let share = @"\\share" let a,b = x
these lines directly into the interactive
command shell, be sure to follow them Use escape characters Reconstruction and value reuse
up with two semicolons “;;”. let shareln = "\\\\share\n" let y = (x,(a,b))
If you have any comments, corrections
or suggested additions please send 3 Numbers Reconstruction into a 3 tuple (triple)
let z = (x,y,a)
them to chance@[Link].
type is int16 = System.Int16 Partial deconstruction triple
1. Comments let int16num = 10s let ((a',b'),y',a'') = z
There are a few different kinds of type is int32 = System.Int32
let int32num = 10
5 Lists, Arrays, Seqs : Generation
comments in F#. Comment blocks,
which are placed between (* and *) type is int64 = System.Int64 Creates the list [0 ; 2 ; 4]
markers. let int64num = 10L let lsinit = [Link] 3
(fun i -> i * 2)
Line by line comments which follow // type is float32, single or [Link]
until the end of a line and xml doc let float32num = 10.0f Creates same list as above
let lsgen = [ 0 ; 2 ; 4]
comments which follow /// and allow
type is float, double or [Link]
the programmer to place comments in let floatnum = 10.0 Creates the list [0;2;4;6;8]
xml tags that can be used to generate let lsgen2 = [0 .. 2 .. 8]
xml documents. convert to int64
let int64frm32 = int64 int32num
[Link]
F# Cheat Sheet
Can also do above one increment at a Same as above one increment at a time 6 Lists, Arrays, Seqs : Consuming
time to get [0;1;2;3;4;5;6;7;8] to get [|0;1;2;3;4;5;6;7;8|]
let lsgen2' = [0..8] let argen2' = [|0..8|] "left" fold starts from the left of the list,
the "right" fold does the opposite
Creates a list [0.0; 0.5; 1.0; 1.5] Create an array [0.0; 0.5; 1.0; 1.5] List.fold_left
let lsgen3 = let argen3 = (fun state a -> state + 1 ) 0
[for i in 0..3 -> 0.5 * float i] [|for i in 0..3 -> 0.5 * float i|] [ for i in 0 .. 9 -> true]
Put other steps into a generator Put other computation steps into the Reduce doesn’t require the starter
let lsgen3' = generator argument
[for i in 0..3 -> let argen3' = List.reduce_left
printf "Adding %d\n" i [|for i in 0..3 -> (fun accum a -> accum + a )
0.5 * float i] printf "Adding %d\n" i [0..9]
0.5 * float i|]
Place -1 at the head of a list Square all of the elements in a list
let inserted = -1 :: lsgen2' Creating a seq -- remember these are [Link] (fun x -> x * x) [1..10]
lazy
Concatenation let s = Prints all the items of a list
let concat = lsgen2 @ lsgen2' seq { for i in 0 .. 10 do yield i } [Link]
(fun x -> printf "%d" x) [1..10]
Create an array [|0 ; 2 ; 4|] Illustrate laziness – consume the seq
let arinit = [Link] 3 below and note the difference from the Same examples for arrays
(fun i -> i * 2) generated array. Array.fold_left
let s2 = (fun state a -> state + 1 ) 0
Create same array as above seq { for i in 0 .. 10 do [| for i in 0 .. 9 -> true|]
let argen = [| 0 ; 2 ; 4|] printf "Adding %d\n" i
yield i } Array.reduce_left
(fun accum a -> accum + a )
[|0..9|]
Create the array [|0;2;4;6;8|]
let argen2 = [|0 .. 2 .. 8|]
Squares all the elements in the array
[Link]
(fun x -> x * x) [| 1 .. 10 |]
[Link]
F# Cheat Sheet
8 Composition Operators
Prints all the items of an array the |> operator is very helpful for Apply those functions iteratively
[Link] chaining arguments and functions listOfPrintActions
(fun x -> printf "%d" x) together |> [Link] (fun i a -> a i)
[|1..10|] let piped = [0..2] |> [Link]
Anonymous function (applied to 2)
Access all elements of an array from 2 the >> operator is very helpful for (fun x -> x * x) 2
on composing functions
let arr = [|for i in 0..3 -> i|] open System Anonymous function (applied to
arr.[2..] let composedWriter = tuple,which is deconstructed inside)
string >> let arg = (3,2)
Access elements between 2 and 4 [Link] (fun (x,y) -> x * y) arg
(inclusive)
let arr = [|for i in 0..3 -> i|] 9 Functions as values 10 Union Types
arr.[2..4]
Create a function of 3 arguments Discriminated Union
Access all elements of an array up to 4 let add x y z = x + y + z type option<'a> =
let arr = [|for i in 0..3 -> i|] | Some of 'a
arr.[..4] | None
Currying example
let addWithFour= add 4
Seq also has iter, fold, map and reduce
[Link]
(fun accum a -> accum + a)
Augmented Discriminated Union
Apply remaining arguments type BinTree<‟a> =
(seq { for i in 0 .. 9 do
addWithFour 2 10 | Node of
yield i })
BinTree<‟a> * „a *
BinTree<‟a>
Take a function as an argument | Leaf
7 Arrays: Manipulating let runFuncTenTimes f a = with member [Link]() =
[ for 0..9 -> f a] match self with
Array elements can be updated | Leaf -> 0
Return a list of functions as arguments | Node(l,_,r) -> 1 +
let arrayone = [|0..8|]
let listOfPrintActions = [Link]() +
arrayone.[0] <- 9
[ for 0 .. 10 -> [Link]()
printf “%s\n”]
[Link]
F# Cheat Sheet
11 Types: Records Subclass Object Expressions
type MyClass() = let foo =
type Person = {name:string;age:int} inherit BaseClass() {new MyAbsFoo with
let someval = “SomeVal” member [Link]()=”Bar”}
let paul = {name="Paul";age=35} let mutable myIntValue = 1
member [Link](x,y) = Augmenting Existing Objects (note:
let paulstwin = gxy
augmented members only available
{paul with name="jim"} static member StaticMethod(x,y)=
fxy when augmenting module is opened)
member override [Link]() = open [Link]
do printf "Name %s, Age %d" [Link]()+ type XmlDocument() =
[Link] [Link] myIntValue member [Link]() =
[Link]
Augmenting Records
Static Upcasting
Interface let strAsObj =
type Person = {name:string;age:int} type MyAbsFoo =
with member [Link]() = let str = “Hello”
abstract Foo:unit->string
([Link],[Link]) str :> obj
type MyFooClass() =
let mutable myfoo =”Foo” Dynamic Downcasting
12 Types: OOP member [Link] let objSub (o:‟a when „a:>object) =
with get () = myfoo o :?> SomeSubType
Classes and set v = myfoo<-v
interface MyAbsFoo with 13 Pattern Matching
member [Link]() = myfoo
type BaseClass()= end
let mutable myIntValue=1 Basic
member [Link] let f (x:option<int>) =
with get() = myIntValue match x with
and set v = myIntValue<-v | None -> ()
abstract member | Some(i) -> printf “%d” i
InheritNum:unit->int
default [Link]() = As a function definition
[Link] + 1 let f = function
| None -> ()
| Some(i) -> printf “%d” i
[Link]
F# Cheat Sheet
Add block that runs whether exception 15 Loops
With when operation is thrown or not for i in 0..10 do
let f = function try printf “%d” i
| None -> () [Link]() done
| Some(i) when i=0 -> () finally
| Some(i) when i>0 ->printf“%d”i [Link]() Over an IEnumerable
for x in xs do
Common matches on a literal Raise an exception in code printf “%s\n”([Link]())
let f x = done
-Shorthand
match x with let f x =
| 0 | 1 as y -> f y if not [Link] then
While
| i -> printf “%d” i invalid_arg “f:x is not valid” let mutable mutVal = 0
else [Link]() while mutVal<10 do
mutVal <- mutVal + 1
Wildcard done
let f = function -Full
| 0 | 1 as y -> printf “Nothing” let f x =
| _ -> printf “Something” if not [Link]() then
16 Async Computations
raise (Note: [Link] should
14 Exceptions (InvalidOperationException be referenced in your project – as of the
try (“x must support process”)) CTP - to get the augmented async
[Link]() else [Link]() methods available in existing IO
with | ex -> operations)
printf “%s\n” [Link]
Create your own Basic computation that returns
With (exception) type test exception InvalidProcess of string
try
Async<int> that will yield 1 when
[Link]() try executed
with raise InvalidProcess(“Raising Exn”) let basic = async { return 1 }
| :? ArgumentException as ex -> with
printf “Bad Argument:\n” | InvalidProcess(str) -> Composing expressions and applying to
| exn -> printf “%s\n” [Link] printf “%s\n” str arguments
let compound num =
async {
let! anum = basic
return num + anum }
[Link]
F# Cheat Sheet
Making sure I/O threads don’t block
Returning existing expressions (Note the MethodAsync convention in Partial Pattern
let composedReturn = “Expert F#” seems to have changed to let (|Xml|_|) doc =
async { return! compound 2} AsyncMethod) if [Link]=”” then None
else Some([Link])
let asyncRead file (numBytes:int)=
Creating Primitives with existing async { let getXml = function
let inStr = [Link](file) | Xml(xml) -> Some(xml) //Xml Matched
Begin/End Async Calls | _ -> None // Xml did not match
let! data = [Link] numBytes
let asyncCall args =
return processData(data) }
[Link]
((fun (callback,asyncState) ->
[Link](args, Execution Methods (apply the async 18 Compiler Directives and Interop
callback, computation as an argument to these) with other .NET Languages
asyncState)), [Link] Make indentation significant in parsing
[Link]) [Link] (i.e. turn on light syntax)
[Link] #light
Make your own primitive from scratch [Link]
let asyncPrimitive args = Reference a DLL from another .NET
[Link] (fun (con,exn) -> 17 Active Patterns
let result = runSomething args
library (interactive F# scripts only – in
Basic compiled code use normal interface for
if good result then con result let (|Xml|) doc = [Link]
else exn result) reference additions)
#r @“.\src\bin\[Link]”
let getXml = function
Other primitives | Xml(xml) -> xml
[Link] Include a directory in the reference
[Link] Multiple Patterns search (also in interactive scripts only)
[Link] let (|Xml|NoXml|) doc = #I @“[dir path]”
if [Link]=”” then NoXml
else Xml([Link]) For a C# class Foo in a dll with a
method ToString(), invoke just as you
let getXml = function
would an F# class.
| Xml(xml) -> Some(xml)
let foo = Foo()
| NoXml -> None
let s = [Link]()
[Link]
F# Cheat Sheet
To have code run only in when
working with the compiled version
#if COMPILED
…code
#endif
For example, when writing a windowed
application that you test in script, but
eventually compile to run
let window =
Window(Title=”My Window”)
#if COMPILED
[<STAThread>]
do
let app = Application in
[Link](window) |> ignore
#endif
… later in script (.fsx) file …
[Link]()
Version 1.01
You can always get the most recent
updates to this cheat sheet from
[Link]
A6 Systems, LLC is an Austin, TX
based company that provides
consulting services and F# QuickStart
training.
[Link]