val a : int

Full name: index.a
val b : float

Full name: index.b
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val mutable c : int

Full name: index.c
val r : int ref

Full name: index.r
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Multiple items
type Point =
  new : x:int * y:int -> Point
  member X : int
  member Y : int

Full name: index.Point

--------------------
new : x:int * y:int -> Point
val x : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val y : int
member Point.X : int

Full name: index.Point.X
member Point.Y : int

Full name: index.Point.Y
val index : int
val mutable index : int

Full name: index.index
val myFunction : x:int -> y:int -> int

Full name: index.MyMod.myFunction
val myFunction2 : x:int -> y:int -> int

Full name: index.MyMod.myFunction2
val privateFunction : (int -> int)
val z : int
val highOrderFunction : f:('a -> 'b) -> y:'a -> 'b

Full name: index.MyMod.highOrderFunction
val f : ('a -> 'b)
val y : 'a
val recursiveFuncion : x:int -> int

Full name: index.MyMod.recursiveFuncion
val memoizeFunction : (int -> int)

Full name: index.MyMod.memoizeFunction
val cache : System.Collections.Generic.Dictionary<int,int>
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Dictionary<'TKey,'TValue> =
  new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
  member Add : key:'TKey * value:'TValue -> unit
  member Clear : unit -> unit
  member Comparer : IEqualityComparer<'TKey>
  member ContainsKey : key:'TKey -> bool
  member ContainsValue : value:'TValue -> bool
  member Count : int
  member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  member Item : 'TKey -> 'TValue with get, set
  ...
  nested type Enumerator
  nested type KeyCollection
  nested type ValueCollection

Full name: System.Collections.Generic.Dictionary<_,_>

--------------------
System.Collections.Generic.Dictionary() : unit
System.Collections.Generic.Dictionary(capacity: int) : unit
System.Collections.Generic.Dictionary(comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>) : unit
System.Collections.Generic.Dictionary(capacity: int, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary.ContainsKey(key: int) : bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
System.Collections.Generic.Dictionary.Add(key: int, value: int) : unit
type MyClass =
  static member MyFunction : ?x:int * ?y:int -> int
  static member MyFunction2 : [<ParamArray>] rest:int array -> int

Full name: index.MyClass
static member MyClass.MyFunction : ?x:int * ?y:int -> int

Full name: index.MyClass.MyFunction
val x : int option
val y : int option
val defaultArg : arg:'T option -> defaultValue:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.defaultArg
static member MyClass.MyFunction2 : [<ParamArray>] rest:int array -> int

Full name: index.MyClass.MyFunction2
Multiple items
type ParamArrayAttribute =
  inherit Attribute
  new : unit -> ParamArrayAttribute

Full name: System.ParamArrayAttribute

--------------------
ParamArrayAttribute() : unit
val rest : int array
type 'T array = 'T []

Full name: Microsoft.FSharp.Core.array<_>
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val reduce : reduction:('T -> 'T -> 'T) -> array:'T [] -> 'T

Full name: Microsoft.FSharp.Collections.Array.reduce
static member MyClass.MyFunction : ?x:int * ?y:int -> int
argument y : int option
static member MyClass.MyFunction2 : [<ParamArray>] rest:int array -> int
Multiple items
type AbstractClassAttribute =
  inherit Attribute
  new : unit -> AbstractClassAttribute

Full name: Microsoft.FSharp.Core.AbstractClassAttribute

--------------------
new : unit -> AbstractClassAttribute
Multiple items
type AbstractBaseClass =
  new : unit -> AbstractBaseClass
  abstract member Add : int -> int -> int
  abstract member Pi : float
  override Add : x:int -> y:int -> int

Full name: index.AbstractBaseClass

--------------------
new : unit -> AbstractBaseClass
abstract member AbstractBaseClass.Add : int -> int -> int

Full name: index.AbstractBaseClass.Add
abstract member AbstractBaseClass.Pi : float

Full name: index.AbstractBaseClass.Pi
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val this : AbstractBaseClass
override AbstractBaseClass.Add : x:int -> y:int -> int

Full name: index.AbstractBaseClass.Add
type MyInterface =
  interface
    abstract member Square : float -> float
  end

Full name: index.MyInterface
abstract member MyInterface.Square : float -> float

Full name: index.MyInterface.Square
Multiple items
type StructAttribute =
  inherit Attribute
  new : unit -> StructAttribute

Full name: Microsoft.FSharp.Core.StructAttribute

--------------------
new : unit -> StructAttribute
Multiple items
type MyStruct =
  struct
    new : x:float * y:float -> MyStruct
    member X : float
    member Y : float
  end

Full name: index.MyStruct

--------------------
MyStruct()
new : x:float * y:float -> MyStruct
val x : float
val y : float
member MyStruct.X : float

Full name: index.MyStruct.X
val __ : byref<MyStruct>
member MyStruct.Y : float

Full name: index.MyStruct.Y
type Double =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 3 overloads
    static val MinValue : float
    static val MaxValue : float
    static val Epsilon : float
    static val NegativeInfinity : float
    static val PositiveInfinity : float
    ...
  end

Full name: System.Double
val x : Double
member Double.Square : float

Full name: index.Square
type Math =
  static val PI : float
  static val E : float
  static member Abs : value:sbyte -> sbyte + 6 overloads
  static member Acos : d:float -> float
  static member Asin : d:float -> float
  static member Atan : d:float -> float
  static member Atan2 : y:float * x:float -> float
  static member BigMul : a:int * b:int -> int64
  static member Ceiling : d:decimal -> decimal + 1 overload
  static member Cos : d:float -> float
  ...

Full name: System.Math
Math.Sqrt(d: float) : float
Multiple items
type DerivedClass =
  inherit AbstractBaseClass
  interface MyInterface
  new : param1:int -> DerivedClass
  new : param1:int * param2:int -> DerivedClass
  override Add : int -> int -> int
  member Area : int
  member Area2 : int
  override Pi : float
  member Area : int with set
  member Area2 : int with set
  ...

Full name: index.DerivedClass

--------------------
new : param1:int -> DerivedClass
new : param1:int * param2:int -> DerivedClass
val param1 : int
val param2 : int
val mutable area : int
val this : DerivedClass
override DerivedClass.Add : int -> int -> int

Full name: index.DerivedClass.Add
override DerivedClass.Pi : float

Full name: index.DerivedClass.Pi
member DerivedClass.Area : int with set

Full name: index.DerivedClass.Area
val set : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
val v : int
static member DerivedClass.StaticValue : int

Full name: index.DerivedClass.StaticValue
override DerivedClass.Square : x:float -> float

Full name: index.DerivedClass.Square
val o1 : DerivedClass

Full name: index.o1
val o2 : MyInterface

Full name: index.o2
abstract member MyInterface.Square : float -> float
val o3 : MyInterface

Full name: index.o3
val reverse : x:'a * y:'b * z:'c * u:'d -> 'd * 'c * 'b * 'a

Full name: index.reverse
val x : 'a
val y : 'b
val z : 'c
val u : 'd
val myTuple : int * float * string * int list

Full name: index.myTuple
val li : int list

Full name: index.li
type MyRecord =
  {id: int;
   qt: float;
   name: string;
   li: int list;}

Full name: index.MyRecord
MyRecord.id: int
MyRecord.qt: float
MyRecord.name: string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
MyRecord.li: int list
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val myRecord : MyRecord

Full name: index.myRecord
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
val id2 : int

Full name: index.id2
val name2 : string

Full name: index.name2
val myRecord2 : MyRecord

Full name: index.myRecord2
type Term =
  | Var of string
  | Fun of string * Term
  | App of Term * Term

Full name: index.Term
union case Term.Var: string -> Term
union case Term.Fun: string * Term -> Term
union case Term.App: Term * Term -> Term
val formatTerm : term:Term -> string

Full name: index.formatTerm
val term : Term
val n : string
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val x : string
val b : Term
val f : Term
type Shape =
  | Rectangle of width: float * length: float
  | Circle of radius: float
  | Prism of width: float * float * height: float

Full name: index.Shape
union case Shape.Rectangle: width: float * length: float -> Shape
union case Shape.Circle: radius: float -> Shape
union case Shape.Prism: width: float * float * height: float -> Shape
val matchShapeList : _arg1:Shape list -> float option

Full name: index.matchShapeList
union case Option.None: Option<'T>
val shape : Shape
val length : float
union case Option.Some: Value: 'T -> Option<'T>
val r : float
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val rest : Shape list
val i : int
active recognizer Even: int -> Choice<unit,unit>

Full name: index.( |Even|Odd| )
active recognizer Odd: int -> Choice<unit,unit>

Full name: index.( |Even|Odd| )
val str : string
type Int32 =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 3 overloads
    static val MaxValue : int
    static val MinValue : int
    static member Parse : s:string -> int + 3 overloads
    static member TryParse : s:string * result:int -> bool + 1 overload
  end

Full name: System.Int32
Int32.TryParse(s: string, result: byref<int>) : bool
Int32.TryParse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider, result: byref<int>) : bool
Double.TryParse(s: string, result: byref<float>) : bool
Double.TryParse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider, result: byref<float>) : bool
val f : float
active recognizer Integer: string -> int option

Full name: index.( |Integer|_| )
active recognizer Float: string -> float option

Full name: index.( |Float|_| )
namespace System.Text
namespace System.Text.RegularExpressions
val regex : string
Multiple items
type Regex =
  new : pattern:string -> Regex + 1 overload
  member GetGroupNames : unit -> string[]
  member GetGroupNumbers : unit -> int[]
  member GroupNameFromNumber : i:int -> string
  member GroupNumberFromName : name:string -> int
  member IsMatch : input:string -> bool + 1 overload
  member Match : input:string -> Match + 2 overloads
  member Matches : input:string -> MatchCollection + 1 overload
  member Options : RegexOptions
  member Replace : input:string * replacement:string -> string + 5 overloads
  ...

Full name: System.Text.RegularExpressions.Regex

--------------------
Regex(pattern: string) : unit
Regex(pattern: string, options: RegexOptions) : unit
Regex.Match(input: string, pattern: string) : Match
Regex.Match(input: string, pattern: string, options: RegexOptions) : Match
val m : Match
property Group.Success: bool
val x : Group
property Match.Groups: GroupCollection
property Capture.Value: string
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val tail : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.tail
val parseDate : str:string -> DateTime

Full name: index.parseDate
active recognizer ParseRegex: string -> string -> string list option

Full name: index.( |ParseRegex|_| )
val m : int
val d : int
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
val max : x:'a -> y:'a -> 'a (requires comparison)

Full name: index.max
val x : 'a (requires comparison)
val y : 'a (requires comparison)
val makeNoise : animal:'a -> unit (requires member MakeNoise)

Full name: index.makeNoise
val animal : 'a (requires member MakeNoise)
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
Multiple items
type Dog =
  new : unit -> Dog
  member MakeNoise : unit -> unit

Full name: index.Dog

--------------------
new : unit -> Dog
member Dog.MakeNoise : unit -> unit

Full name: index.Dog.MakeNoise
Multiple items
type Cat =
  new : unit -> Cat
  member MakeNoise : unit -> unit

Full name: index.Cat

--------------------
new : unit -> Cat
member Cat.MakeNoise : unit -> unit

Full name: index.Cat.MakeNoise
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
Random() : unit
Random(Seed: int) : unit
val initInfinite : initializer:(int -> 'T) -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.initInfinite
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
  interface IEnumerable
  interface IComparable
  interface IEnumerable<KeyValuePair<'Key,'Value>>
  interface ICollection<KeyValuePair<'Key,'Value>>
  interface IDictionary<'Key,'Value>
  new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
  member Add : key:'Key * value:'Value -> Map<'Key,'Value>
  member ContainsKey : key:'Key -> bool
  override Equals : obj -> bool
  member Remove : key:'Key -> Map<'Key,'Value>
  ...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val unbox : value:obj -> 'T

Full name: Microsoft.FSharp.Core.Operators.unbox
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.filter
val take : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.take
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.sortBy
val toList : source:seq<'T> -> 'T list

Full name: Microsoft.FSharp.Collections.Seq.toList
property DateTime.Now: DateTime
namespace System.Timers
Multiple items
type Timer =
  inherit Component
  new : unit -> Timer + 1 overload
  member AutoReset : bool with get, set
  member BeginInit : unit -> unit
  member Close : unit -> unit
  member Enabled : bool with get, set
  member EndInit : unit -> unit
  member Interval : float with get, set
  member Site : ISite with get, set
  member Start : unit -> unit
  member Stop : unit -> unit
  ...

Full name: System.Timers.Timer

--------------------
Timers.Timer() : unit
Timers.Timer(interval: float) : unit
module Observable

from Microsoft.FSharp.Control
val map : mapping:('T -> 'U) -> source:IObservable<'T> -> IObservable<'U>

Full name: Microsoft.FSharp.Control.Observable.map
val merge : source1:IObservable<'T> -> source2:IObservable<'T> -> IObservable<'T>

Full name: Microsoft.FSharp.Control.Observable.merge
val pairwise : source:IObservable<'T> -> IObservable<'T * 'T>

Full name: Microsoft.FSharp.Control.Observable.pairwise
val partition : predicate:('T -> bool) -> source:IObservable<'T> -> IObservable<'T> * IObservable<'T>

Full name: Microsoft.FSharp.Control.Observable.partition
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
namespace System.Net
type WebRequest =
  inherit MarshalByRefObject
  member Abort : unit -> unit
  member AuthenticationLevel : AuthenticationLevel with get, set
  member BeginGetRequestStream : callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginGetResponse : callback:AsyncCallback * state:obj -> IAsyncResult
  member CachePolicy : RequestCachePolicy with get, set
  member ConnectionGroupName : string with get, set
  member ContentLength : int64 with get, set
  member ContentType : string with get, set
  member Credentials : ICredentials with get, set
  member EndGetRequestStream : asyncResult:IAsyncResult -> Stream
  ...

Full name: System.Net.WebRequest
Net.WebRequest.Create(requestUri: Uri) : Net.WebRequest
Net.WebRequest.Create(requestUriString: string) : Net.WebRequest
Multiple items
type Uri =
  new : uriString:string -> Uri + 5 overloads
  member AbsolutePath : string
  member AbsoluteUri : string
  member Authority : string
  member DnsSafeHost : string
  member Equals : comparand:obj -> bool
  member Fragment : string
  member GetComponents : components:UriComponents * format:UriFormat -> string
  member GetHashCode : unit -> int
  member GetLeftPart : part:UriPartial -> string
  ...

Full name: System.Uri

--------------------
Uri(uriString: string) : unit
Uri(uriString: string, uriKind: UriKind) : unit
Uri(baseUri: Uri, relativeUri: string) : unit
Uri(baseUri: Uri, relativeUri: Uri) : unit
namespace System.IO
Multiple items
type StreamReader =
  inherit TextReader
  new : stream:Stream -> StreamReader + 9 overloads
  member BaseStream : Stream
  member Close : unit -> unit
  member CurrentEncoding : Encoding
  member DiscardBufferedData : unit -> unit
  member EndOfStream : bool
  member Peek : unit -> int
  member Read : unit -> int + 1 overload
  member ReadLine : unit -> string
  member ReadToEnd : unit -> string
  ...

Full name: System.IO.StreamReader

--------------------
IO.StreamReader(stream: IO.Stream) : unit
IO.StreamReader(path: string) : unit
IO.StreamReader(stream: IO.Stream, detectEncodingFromByteOrderMarks: bool) : unit
IO.StreamReader(stream: IO.Stream, encoding: Text.Encoding) : unit
IO.StreamReader(path: string, detectEncodingFromByteOrderMarks: bool) : unit
IO.StreamReader(path: string, encoding: Text.Encoding) : unit
IO.StreamReader(stream: IO.Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : unit
IO.StreamReader(path: string, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : unit
IO.StreamReader(stream: IO.Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
IO.StreamReader(path: string, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
module Option

from Microsoft.FSharp.Core
val bind : binder:('T -> 'U option) -> option:'T option -> 'U option

Full name: Microsoft.FSharp.Core.Option.bind
val query : Linq.QueryBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
Multiple items
type MeasureAttribute =
  inherit Attribute
  new : unit -> MeasureAttribute

Full name: Microsoft.FSharp.Core.MeasureAttribute

--------------------
new : unit -> MeasureAttribute

F# for Scala Developers

Walking into the dark side

meets

Scala and F# Madrid Meetup groups

How much do Scala and F# look alike?

  • Bring (non-strict) Functional Programming to Java and .NET
  • Full compatibility with their host platforms
  • Built-in functional libraries
  • Static safety with type inference
  • Mostly expression based (side-effects also allowed)
  • Open source projects with vibrant communities

How much do Scala and F# differ?

Scala

  • Embraces both Object Oriented and Functional Programming
  • Designed not to scare OOP developers: curly-brace
  • Very powerful and flexible syntax
  • Very rich class system
  • Language team works separately from Java team

How much do Scala and F# differ?

F#

  • Multi-paradigm but functional-first
  • Inherited from Ocaml: indentation sensitive
  • Less flexible syntax, more focused on consistency
  • Three flavors: project (.fs), script (.fsx) and signature (.fsi) files
  • Language team works together (more or less) with .NET team

Functional features like generics and tail-call instructions are native to the platform

Let's see some code examples...

Constants, Variables and null

Scala

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
val a = 5                 // Type inferred constant declaration
val b: Double = 5.0       // Explicitly typed constant declaration

var c = 5                 // Variable declaration
c = 10                    // Mutation

class Point(xc: Int, yc: Int) {
  val x: Int = xc
  val y: Int = yc
}

val p: Point = null       // null allowed for custom classes

F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
let a = 5                 // Type inferred constant declaration
let b: float = 5.         // Explicitly typed constant declaration
let a = 2                 // Shadowing

// Verbosity penalty for mutability
let mutable c = 5         // Variable declaration
c <- 10                   // Mutation

// Reference cells: used mainly before F# 4.0
// to capture mutable variables in closures
let r = ref 5
printfn "%i" !r           // Accessing cell content
r := 2                    // Mutating cell content

type Point(x: int, y: int) =
  member val X = x
  member val Y = y

// Doesn't compile, null not allowed in custom classes
//let p: Point = null

Imperative loops

Scala

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
for (index <- 1 to 5) {
  println(s"$index times 5 is ${index * 5}")
}

var index = 1
while (index < 6) {
  println(s"$index times 5 is ${index * 5}")
  index = index + 1
}

F#

As in Scala, break and continue are missing from the language. Recursion or stream functions are preferred.

1: 
2: 
3: 
4: 
5: 
6: 
7: 
for index = 1 to 5 do
  printfn "%i times 5 is %i" index (index * 5)

let mutable index = 1
while index < 6 do
  printfn "%i times 5 is %i" index (index * 5)
  index <- index + 1

Functions

Scala

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
def myFunction(x: Int, y: Int) = {
  def privateFunction(z: Int) = z * 2
  privateFunction(x + y)
}

def curryFunction(x: Int)(y: Int) = x * y

def highOrderFunction(f: Int => Int, y: Int) = f(y)

def recursiveFuncion(x: Int): Int =
  if (x == 1) 1 else x * (recursiveFuncion(x - 1))

// Function as object instead of method
val myLambda = (x: Int, y: Int) => x * y

// Lambda shortcut, not possible in F#
val myLambda2: Function2[Int,Int,Int] = _*_

Scala

Memoize Pattern

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
val memoizeFunction = {
  val cache = scala.collection.mutable.HashMap.empty[Int,Int]
  (x: Int) => {
    if (cache.contains(x) == false) {
      println(s"Adding $x to cache...")
      cache += (x -> x * 2)
    }
    cache(x)
  }
}

F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
module MyMod =
  let myFunction x y = x + y

  let myFunction2 x y =
    let privateFunction z = z * 2
    // let privateFunction = fun z -> z * 2   // Same effect
    privateFunction (x + y)

  let highOrderFunction f y = f y

  let rec recursiveFuncion x =
    if x = 1 then x else x * (recursiveFuncion (x - 1))

  let memoizeFunction =
    let cache = System.Collections.Generic.Dictionary<int, int>()
    fun x ->
      if cache.ContainsKey x |> not then
        cache.Add(x, x * 2)
      cache.[x]

F#

As seen above, functions in F# are usually contained in modules (curried by default)

Optional and rest parameters are only accepted in non-curried class methods

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
open System

type MyClass =
  static member MyFunction(?x, ?y) =
    (defaultArg x 5) + (defaultArg y 10)
  static member MyFunction2([<ParamArray>] rest: int array) =
    Array.reduce (+) rest

MyClass.MyFunction(y = 4)
MyClass.MyFunction2(1, 2, 3)

Classes

Scala

Classes are very powerful in Scala and different from F#:

  • Singleton objects
  • Traits and abstract types
  • Compound types and mixins

F#

  • F# doesn't focus on classes
  • Their main purpose is compatibility with .NET Base Class Library
  • Mostly same functionality as C# with different Syntax and some additional features (like primary constructors)
  • Interfaces are just abstract classes without default method implementations
  • No mixins, only multiple interface implementation is possible (extension methods are allowed)
  • Object Expressions allow dynamic implementation of interfaces

Abstract classes, interfaces and structs (value classes)

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
[<AbstractClass>]                         // If at least one member lacks
type AbstractBaseClass() =                // implementation, the class must
  abstract member Add: int -> int -> int  //  be marked as abstract
  abstract member Pi: float
  default this.Add x y = x + y            // Default implementation

type MyInterface =                        // Interfaces are just abstract
  abstract member Square: float -> float  // classes without implementations

[<Struct>]                                // Memory for structs is allocated
type MyStruct(x: float, y: float) =       // on the stack, not the heap
  member __.X = x                         // Instances are passed by value,
  member __.Y = y                         // not by reference

type System.Double with                   // Type extension
  member x.Square = System.Math.Sqrt(x)
 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
type DerivedClass(param1, param2) =
   inherit AbstractBaseClass()                // Inheritance
   let mutable area = 0                       // Private field
   new(param1) = DerivedClass(param1, 5)      // Secondary constructor

   override this.Add _ _ = param1 + param2
   override this.Pi = 3.14                    // Getter-only property

   member this.Area
      with get() = area                       // Getter-Setter property
      and set(v) = area <- v
   member val Area2 = 0 with get, set         // Auto implemented property

   static member StaticValue = 5              // Static members are allowed

   interface MyInterface with                 // Interface implementation
      member this.Square x = x * x            // (always explicit)

Object expressions

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
let o1 = DerivedClass(4)          // new keyword is optional
//o1.Square 5.                    // Cannot access interface methods implicitly
let o2: MyInterface = upcast o1   // Casting is automatic when passing arguments
printfn "%f" (o2.Square 5.)

let o3 =                          // Object expressions create an anonymous object
  { new MyInterface with          // implementing the interface
    member __.Square x = x ** 2. }
printfn "%f" (o3.Square 5.)

Tuples and Records

In F#, tuples, records (lightweight classes) and discriminated unions (ADT) are usually preferred, with logic separated in module functions.

Tuples in Scala

1: 
2: 
3: 
4: 
5: 
def reverse(x: Int, y: Double, z: String, u: List[Int]) = (u, z, y, x)
val myTuple = (1, 2., "hola", List(1,2,3))
val (_,_,_,_li) = myTuple              // Destructuring
myTuple._4                             // Direct access to members
//reverse(myTuple)                     // Error

Tuples in F#

1: 
2: 
3: 
4: 
5: 
let reverse(x, y, z, u) = (u, z, y, x)
let myTuple = 1, 2., "hola", [1;2;3]   // Parens can be omitted
let (_,_,_,li) = myTuple               // Destructuring
//myTuple._4                           // No direct acccess to members but...
reverse myTuple                        // can be destructured in function args

F# Records

Named tuples or lightweight classes, if you must

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
// Beware! In F# commas are only for tuples. Separating statements, members,
// list items, etc. is done with either semicolons or line breaks
type MyRecord = { id: int; qt: float; name: string; li: int list }

let myRecord = { id = 1; qt = 2.; name = "hola"; li = [1;2;3] }

myRecord.id                                 // Member access
let { id = id2; name = name2 } = myRecord   // Destructuring
let myRecord2 = { myRecord with qt = 5. }   // Copying

We can reach a similar effect in Scala marking constructor parameters as fields

1: 
2: 
class MyRecord(val id: Int, val qt: Double,
               val name: String, val li: List[Int]) {}

Algebraic Data Types and Pattern Matching

Scala

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
sealed abstract class Term
case class Var(name: String) extends Term
case class Fun(arg: String, body: Term) extends Term
case class App(f: Term, v: Term) extends Term

def formatTerm(term: Term): String = term match {
  case Var(n)    => n
  case Fun(x, b) => s"^$x.${formatTerm(b)}"
  case App(f, v) => s"(${formatTerm(f)} ${formatTerm(v)})"
}

println(formatTerm(Fun("x", Fun("y", App(Var("x"), Var("y"))))))

F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
type Term =
  | Var of string
  | Fun of string * Term
  | App of Term * Term

// Compiler warns you if the matching is not comprehensive
let rec formatTerm term =
  match term with
  | Var(n)    -> sprintf "%s" n
  | Fun(x, b) -> sprintf "^%s.%s" x (formatTerm b)
  | App(f, b) -> sprintf "(%s %s)" (formatTerm f) (formatTerm b)

// Pipelining is very idiomatic in F#
Fun("x", Fun("y", App(Var("x"), Var("y"))))
|> formatTerm
|> printfn "%s"

F# (a more contrived example)

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
type Shape =
  | Rectangle of width: float * length: float
  | Circle of radius: float
  | Prism of width: float * float * height: float

let rec matchShapeList = function             // Shortcut
  | [] -> None                                // Empty list
  | [shape] ->                                // Single item
    match shape with                          
    | Rectangle(length, 10.) -> Some(length)  // Constant
    | Circle r when r > 5.0 -> Some(r)        // Guard
    | _ -> failwith "Unknown shape"
  | _::rest -> matchShapeList rest            // Wildcard

Scala Extractor Objects

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
object Even {
  def unapply(x: Int) =
    if (x % 2 == 0) Some(x) else None
}

object Odd {
  def unapply(x: Int) =
    if (x % 2 == 0) None else Some(x)
}

println(5 match {
  case Even(_) => "Hello"
  case Odd(_) => "Goodbye"
})

F# Exhaustive Active Patterns

1: 
2: 
3: 
4: 
5: 
let (|Even|Odd|) i =
  if i % 2 = 0 then Even else Odd

match 5 with Even -> "Hello" | Odd -> "Goodbye"
|> printfn "%s"

F# Partial Active Pattern

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
let (|Integer|_|) (str: string) =
  match System.Int32.TryParse str with
  | (true, i) -> Some i | (false, _) -> None

let (|Float|_|) (str: string) =
  match System.Double.TryParse str with
  | (true, f) -> Some f | (false, _) -> None

match "Hola" with
| Integer i -> printfn "%d : Integer" i
| Float f -> printfn "%f : Floating point" f
// Appease the compiler
| _ as str -> printfn "%s : Not matched" str

F# Parameterized Active Patterns

Specializing the pattern by passing extra parameters

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
open System.Text.RegularExpressions
let (|ParseRegex|_|) regex str =
   match Regex.Match(str, regex) with
   | m when not m.Success -> None
   | m -> [for x in m.Groups -> x.Value] |> List.tail |> Some

let parseDate str =
  match str with
  | ParseRegex @"^(\d{1,2})/(\d{1,2})/(\d{1,2})$"
              [Integer m; Integer d; Integer y]
    -> System.DateTime(y + 2000, m, d)
  | ParseRegex @"^(\d{1,2})/(\d{1,2})/(\d{3,4})$"
              [Integer m; Integer d; Integer y]
    -> System.DateTime(y, m, d)
  | ParseRegex @"^(\d{1,4})-(\d{1,2})-(\d{1,2})$"
              [Integer y; Integer m; Integer d]
    -> System.DateTime(y, m, d)
  | _ -> System.DateTime()

Kitty Break

Kitty Break

Generics

F# generics are very similar to Scala, with a few diferences:

  • Automatic Generalization
    If the function has no dependency on the specific type of a parameter, the type is inferred to be generic

  • Statically Resolved Type Parameters
    Type parameter replaced with actual types at compile time instead of at run time

  • No generics of generics
    Generics are native to .NET platform (no erasures) but on the other hand are more limited (no type classes)

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
// Automatic Generalization
let (|>) x f = f x
// val ( |> ) : x:'a -> f:('a -> 'b) -> 'b

// Constraints
let max x y = if x > y then x else y
// val max : x:'a -> y:'a -> 'a when 'a : comparison

// Syntax for statically resolved type parameters is not beautiful
// and it's mainly intented for core library functions. However it
// can be used with inline functions for neat tricks like duck typing
let inline makeNoise (animal: ^a when ^a : (member MakeNoise: unit->unit)) =
  (^a: (member MakeNoise: unit->unit) animal)

type Dog() = member __.MakeNoise() = printfn "Guau!"
type Cat() = member __.MakeNoise() = printfn "Miau!"

makeNoise(Dog())
makeNoise(Cat())

No generics of generics

Type classes like Functor are not allowed

1: 
Functor.map : ('a->'b) -> 'T<'a> -> 'T<'b>

Instead, _map_ must be implemented for each type (or interface)
1: 
2: 
3: 
List.map  : ('a->'b) -> list<'a> -> list<'b>
Array.map : ('a->'b) -> array<'a> -> array<'b>
Seq.map   : ('a->'b) -> seq<'a> -> seq<'b>

Collections

F# built-in functions and operators and focus only on a few collection types:

Immutable?

Feature

Scala

list

Yes

Linked list

List

seq

Yes

Lazy evaluation

Iterable/Stream

array

No

Random access

Array

map

Yes

Indexed access

Map

set

Yes

Unique items

Set

Fluent APIs

Scala

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
class Person(val name: String, val age: Int) {}
def selectDataRows() = {
  val rnd = scala.util.Random
  for (i <- Stream.from(1))
    yield Map("name" -> s"Person$i",
              "age" -> rnd.nextInt(99))
}

selectDataRows()
  .map(row => new Person(row("name").asInstanceOf[String],
                        row("age").asInstanceOf[Int]))
  .filter(_.name.startsWith("P"))
  .take(20)
  .sortBy(_.age)
  .toList

// There're multiple libraries in Scala for collections
// Akka-Streams, Scalaz-Stream...

F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
type Person = { name: string; age: int }
let getDataRows() =
  let rnd = System.Random()
  Seq.initInfinite (fun i ->
    Map [ ("name", sprintf "Person%i" i |> box)
          ("age", rnd.Next 99  |> box) ])

// It's more idiomatic in F# to use module functions
// and the pipe operator rather than methods

getDataRows()
|> Seq.map (fun row -> { name = unbox row.["name"]
                         age = unbox row.["age"] })
|> Seq.filter (fun p -> p.name.StartsWith("P"))
|> Seq.take 20
|> Seq.sortBy (fun p -> p.age)
|> Seq.toList

// List and Array modules contain the same functions as Seq
// Of course, pipe operator is possible in SCala too

F# Comprehensions

F# allows comprensions similar to those in Haskell or Python

1: 
2: 
3: 
4: 
5: 
let myList  =     [  for i in 1..100 do yield i*i ]
let myArray =     [| for i in 1..100 -> i*i |]
let mySeq   = seq {  for i in 1..100 -> i*i }

// `->` is a shortcut for `do yield`

In Scala we would just use functions

1: 
List.range(1,101).map(i => i*i)

Observables

F# core library also includes support for Functional Reactive Programming

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
let makeStream interval =
    let t1 = System.DateTime.Now
    let timer = new System.Timers.Timer(float interval, AutoReset=true)
    timer.Start()
    timer.Elapsed
    |> Observable.map (fun t2 -> interval, t2.SignalTime - t1)

let simultaneousStream, nonSimultaneousStream =
    Observable.merge (makeStream 3000) (makeStream 5000)
    |> Observable.pairwise
    |> Observable.partition (fun ((_,t1), (_,t2)) ->
        (t2 - t1).TotalMilliseconds < 50.)

let fizzStream, buzzStream =
    nonSimultaneousStream
    |> Observable.map (fun (ev1,_) -> ev1)
    |> Observable.partition (fun (id,_) -> id=3000)

More info about F# collections at Scott Wlaschin's site

Check also Phillip Trelford's presentation about the performance of F# collection types

List Module Functions

Scala Comprehensions and F# Computation Expressions

In Scala, any type implementing filterWith, map and flatMap can be used with for comprehensions. This allows, for example, dealing with async operations in a monadic way.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
val usdQuote = Future { connection.getCurrentValue(USD) }
val chfQuote = Future { connection.getCurrentValue(CHF) }

val purchase = for {
  usd <- usdQuote
  chf <- chfQuote
  if isProfitable(usd, chf)
} yield connection.buy(amount, chf)

purchase onSuccess {
  case _ => println("Purchased " + amount + " CHF")
}

In F#, this can be done using computation expressions

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
// Parallel I/O
let fetchUrlAsync url = async {
  let req = System.Net.WebRequest.Create(System.Uri url)
  use! resp = req.AsyncGetResponse()
  use stream = resp.GetResponseStream()
  use reader = new System.IO.StreamReader(stream)
  return reader.ReadToEnd()
}

[ "http://fsharp.org/"; "http://www.scala-lang.org/" ]
|> List.map fetchUrlAsync
|> Async.Parallel
|> Async.RunSynchronously
|> printfn "%A"

Computation expressions convert language constructs like let, use, do, for or try in syntactic sugar for continuation passing style operations

F# core has Asynchronous Workflows built-in

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
// Parallel CPU
let rec fib x =
  if x <= 2
  then 1
  else fib(x-1) + fib(x-2)

let fibs =
  [ for i in 0..40 -> async { return fib(i) } ]
  |> Async.Parallel
  |> Async.RunSynchronously
  |> printfn "%A"

Async<'T> is lazy, it will only start running after calling Async.Start or Async.RunSynchronously

Custom computation expressions

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
type MaybeBuilder() =
  member __.Bind(x,f) = Option.bind f x
  member __.Return v = Some v
  member __.ReturnFrom o = o
let maybe = MaybeBuilder()

let riskyOp x y =
  if x + y < 100 then Some(x+y) else None

let execMaybe x = maybe {
  let! a = riskyOp x (x+1)
  let! b = riskyOp a (a+1)
  let! c = riskyOp b (b+1)
  let! d = riskyOp c (c+1)
  return d
}    
execMaybe 5

Besides Bind and Return, there are other methods wich can be implemented by custom computations expressions like Zero, Yield, Combine, For, While or Try

Query expressions

Query expressions provide support for LINQ in F#

1: 
2: 
3: 
4: 
5: 
6: 
query {
    for n in db.Student do
    join e in db.CourseSelection on
          (n.StudentID = e.StudentID)
    count        
}

They express transformations on a data source wich can be translated to another language, usually SQL

1: 
2: 
3: 
SELECT COUNT(*) FROM
Student JOIN CourseSelection
ON Student.StudentID = CourseSelection.StudentID

And now for a couple of unique F# features...

Units of Measure

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
[<Measure>] type km           // Define the measure units
[<Measure>] type mi           // as simple types decorated
[<Measure>] type h            // with Measure attribute

let speed = 90<km> / 1<h>     // Can be combined through
let speed' = 55<mi> / 1<h>    // arithmetic operations

let v1, v2, v3 = 3.1<km/h>, 2.7<km/h>, 1.5<mi/h>
let sum = v1 + v2
//let sum' = v1 + v3          // Error: doesn't compile

// Can be used in a generic way
type Vector3D<[<Measure>] 'u> =
  { x: float<'u>; y: float<'u>; z: float<'u> }

Measure annotations disappear after compilation and thus they have no performance penalty

(Cannot be retrieved by Reflection though)

Type Providers

Static types generated dynamically

CSV Type Provider

JSON

JSON Type Provider

World Bank API REST

Worl Bank Type Provider

Watch this presentation to know more about type providers

Type providers can also be emulated with Scala macros

Flagship Projects

Scala

F#

Web

Play, Lift

Suave

Actors

Akka

Akka.net

Big Data

Spark

Mbrace, Prajna

Visualization

Zeppelin

FsLab

More at the F# space for incubating open community projects

Other platforms

Scala



F#

Want more F#?

These slides were made with FSReveal and no kittens were harmed in the process

And here comes the unasked-for advice!

Remember to focus away and blink regularly when staring at the screen for a long time

Ping me!

@alfonsogcnunez

Github, SlideShare