val a : int
Full name: Index.a
val b : bool
Full name: Index.b
val c : string
Full name: Index.c
val range : int list
Full name: Index.range
val n : int
Multiple items
type LiteralAttribute =
inherit Attribute
new : unit -> LiteralAttribute
Full name: Microsoft.FSharp.Core.LiteralAttribute
--------------------
new : unit -> LiteralAttribute
val item : int * string * float
Full name: Index.item
val id : int
Full name: Index.id
val name : string
Full name: Index.name
val price : float
Full name: Index.price
val productName : string
Full name: Index.productName
val productPrice : float
Full name: Index.productPrice
val numbers : int list
Full name: Index.numbers
val result : string
Full name: Index.result
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
property List.Length: int
val nothing : 'a option
Full name: Index.nothing
union case Option.None: Option<'T>
val something : int option
Full name: Index.something
union case Option.Some: Value: 'T -> Option<'T>
val optionResult : string
Full name: Index.optionResult
val add : n1:int -> n2:int -> int
Full name: Index.add
val n1 : int
val n2 : int
val addWithTwo : (int -> int)
Full name: Index.addWithTwo
type User =
{id: int;
firstName: string;
lastName: string;
email: string;
roles: string list option;}
member fullname : string
Full name: Index.User
User.id: 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<_>
User.firstName: string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
User.lastName: string
User.email: string
User.roles: string list option
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
val x : User
member User.fullname : string
Full name: Index.User.fullname
val user : User
Full name: Index.user
type Shape =
| Square of float
| Rectangle of float * float
| Circle of float
Full name: Index.Shape
union case Shape.Square: float -> Shape
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<_>
union case Shape.Rectangle: float * float -> Shape
union case Shape.Circle: float -> Shape
val square : Shape
Full name: Index.square
val rectangle : Shape
Full name: Index.rectangle
val circle : Shape
Full name: Index.circle
type RoleType =
| Admin = 0
| Manager = 1
| Agent = 2
Full name: Index.RoleType
RoleType.Admin: RoleType = 0
RoleType.Manager: RoleType = 1
RoleType.Agent: RoleType = 2
val role : RoleType
Full name: Index.role
Multiple items
val array : int []
Full name: Index.array
--------------------
type 'T array = 'T []
Full name: Microsoft.FSharp.Core.array<_>
Multiple items
val list : string list
Full name: Index.list
--------------------
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
val sequence : seq<int>
Full name: Index.sequence
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val index : string
Full name: Index.index
val squares : int list
Full name: Index.squares
val isEven : n:int -> bool
Full name: Index.isEven
val even : int list
Full name: Index.even
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 filter : predicate:('T -> bool) -> list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.filter
val x : int
val sortedFruit : string list
Full name: Index.sortedFruit
val sort : list:'T list -> 'T list (requires comparison)
Full name: Microsoft.FSharp.Collections.List.sort
type Person =
{firstName: string;
lastName: string;}
Full name: Index.Person
Person.firstName: string
Person.lastName: string
val people : Person list
Full name: Index.people
val firstNames : string list
Full name: Index.firstNames
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val x : Person
val sortDescending : list:'T list -> 'T list (requires comparison)
Full name: Microsoft.FSharp.Collections.List.sortDescending
val take : count:int -> list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.take
val iter : action:('T -> unit) -> list:'T list -> unit
Full name: Microsoft.FSharp.Collections.List.iter
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
namespace System
namespace System.IO
val bigFiles : seq<string>
Full name: Index.bigFiles
type Directory =
static member CreateDirectory : path:string -> DirectoryInfo + 1 overload
static member Delete : path:string -> unit + 1 overload
static member EnumerateDirectories : path:string -> IEnumerable<string> + 2 overloads
static member EnumerateFileSystemEntries : path:string -> IEnumerable<string> + 2 overloads
static member EnumerateFiles : path:string -> IEnumerable<string> + 2 overloads
static member Exists : path:string -> bool
static member GetAccessControl : path:string -> DirectorySecurity + 1 overload
static member GetCreationTime : path:string -> DateTime
static member GetCreationTimeUtc : path:string -> DateTime
static member GetCurrentDirectory : unit -> string
...
Full name: System.IO.Directory
Directory.EnumerateFiles(path: string) : System.Collections.Generic.IEnumerable<string>
Directory.EnumerateFiles(path: string, searchPattern: string) : System.Collections.Generic.IEnumerable<string>
Directory.EnumerateFiles(path: string, searchPattern: string, searchOption: SearchOption) : System.Collections.Generic.IEnumerable<string>
module Seq
from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val name : string
Multiple items
type FileInfo =
inherit FileSystemInfo
new : fileName:string -> FileInfo
member AppendText : unit -> StreamWriter
member CopyTo : destFileName:string -> FileInfo + 1 overload
member Create : unit -> FileStream
member CreateText : unit -> StreamWriter
member Decrypt : unit -> unit
member Delete : unit -> unit
member Directory : DirectoryInfo
member DirectoryName : string
member Encrypt : unit -> unit
...
Full name: System.IO.FileInfo
--------------------
FileInfo(fileName: string) : unit
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.filter
val fi : FileInfo
property FileInfo.Length: int64
property FileInfo.Name: string
Binding
1:
2:
|
5 = a
let b = 5 = a
|
1:
2:
3:
4:
5:
|
let c =
if a < 5 then
"Less than"
else
"Greater than"
|
Binding cont.
1:
2:
3:
4:
5:
|
let range =
[
for n in 1..10 ->
n * 2
]
|
[2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
|
Module, Namespace, Attribute, Constant
1:
2:
3:
4:
5:
6:
7:
8:
|
namespace SuperApp
[<Literal>]
let meaningOfLife = 42
module Util =
let crackIt = ()
let doCracking = Util.crackIt
|
Tuple
1:
2:
3:
|
let item = (1, "apple", 2.99)
let id, name, price = item
let _, productName, productPrice = item
|
Pattern Matching
1:
2:
3:
4:
5:
6:
|
let numbers = [ 1..10 ]
let result =
match numbers with
| [] -> "Nothing in collection"
| _ -> sprintf "Collection count: %i" numbers.Length
|
Option
1:
2:
3:
4:
5:
6:
7:
|
let nothing = None
let something = Some 1
let optionResult =
match something with
| None -> "nothing something"
| Some n -> sprintf "something: %i" n
|
Function
1:
2:
3:
4:
|
let add n1 n2 =
n1 + n2
add 1 2
|
Partial Application
1:
2:
3:
|
let addWithTwo = (+) 2
addWithTwo 4
|
Record
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
|
type User = {
id: int
firstName: string
lastName: string
email: string
roles: string list option
}
with member x.fullname = sprintf "%s %s" x.firstName x.lastName
let user = {
id = 1
firstName = "pero"
lastName = "peric"
email = "pero@ab.ba"
roles = None
}
|
Discriminated Unions
1:
2:
3:
4:
5:
6:
7:
8:
|
type Shape =
| Square of float
| Rectangle of float * float
| Circle of float
let square = Square 3.
let rectangle = Rectangle(2., 1.5)
let circle = Circle(1.0)
|
Enum
1:
2:
3:
4:
5:
6:
|
type RoleType =
| Admin = 0
| Manager = 1
| Agent = 2
let role = RoleType.Admin
|
Collections
1:
2:
3:
4:
5:
6:
7:
8:
|
let array = [| 1; 2; 4 |]
let list = [
"apple"
"orange"
"peach"
]
let sequence = seq { 0..99 }
let index = list.[0]
|
["apple"; "orange"; "peach"]
|
For & Yield
1:
2:
3:
|
let squares = [
for n in 0..99 do
yield n * n ]
|
[0; 1; 4; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256; 289; 324;
361; 400; 441; 484; 529; 576; 625; 676; 729; 784; 841; 900; 961; 1024; 1089;
1156; 1225; 1296; 1369; 1444; 1521; 1600; 1681; 1764; 1849; 1936; 2025; 2116;
2209; 2304; 2401; 2500; 2601; 2704; 2809; 2916; 3025; 3136; 3249; 3364; 3481;
3600; 3721; 3844; 3969; 4096; 4225; 4356; 4489; 4624; 4761; 4900; 5041; 5184;
5329; 5476; 5625; 5776; 5929; 6084; 6241; 6400; 6561; 6724; 6889; 7056; 7225;
7396; 7569; 7744; 7921; 8100; 8281; 8464; 8649; 8836; 9025; 9216; 9409; 9604;
9801]
|
Filter & Pipe
1:
2:
|
let isEven n = n % 2 = 0
let even = squares |> List.filter (fun x -> isEven x)
|
[0; 4; 16; 36; 64; 100; 144; 196; 256; 324; 400; 484; 576; 676; 784; 900; 1024;
1156; 1296; 1444; 1600; 1764; 1936; 2116; 2304; 2500; 2704; 2916; 3136; 3364;
3600; 3844; 4096; 4356; 4624; 4900; 5184; 5476; 5776; 6084; 6400; 6724; 7056;
7396; 7744; 8100; 8464; 8836; 9216; 9604]
|
Sort
1:
|
let sortedFruit = List.sort [ "pear"; "orange"; "apple" ]
|
["apple"; "orange"; "pear"]
|
Map
1:
2:
3:
4:
5:
6:
7:
|
type Person = { firstName: string; lastName: string }
let people = [
{ firstName = "pero"; lastName = "peric" }
{ firstName = "djuro"; lastName = "djuric" }
{ firstName = "ivo"; lastName = "ivic" } ]
let firstNames = people |> List.map (fun x -> x.firstName)
|
[{firstName = "pero";
lastName = "peric";}; {firstName = "djuro";
lastName = "djuric";}; {firstName = "ivo";
lastName = "ivic";}]
|
Multiple pipes
1:
2:
3:
4:
5:
|
squares
|> List.filter isEven
|> List.sortDescending
|> List.take 5
|> List.iter (fun n -> printfn "%i" n)
|
[9604; 9216; 8836; 8464; 8100]
|
Sequence example
1:
2:
3:
4:
5:
6:
7:
|
open System.IO
let bigFiles =
Directory.EnumerateFiles(@"/Applications/Mail.app/Contents/Resources")
|> Seq.map (fun name -> FileInfo name)
|> Seq.filter (fun fi -> fi.Length > 10000L)
|> Seq.map (fun fi -> fi.Name)
|
seq
["ActionFlagTemplate.pdf"; "ActionReadTemplate.pdf";
"ActionReplyAllTemplate.pdf"; "ActionUnreadTemplate.pdf"; ...]
|
Pros
- Readability and joy to write
- First class function
- Powerful type inference and true strong typed language
- Piping
- Patern matching
- Collections builtin (no namespace imports needed)
- Option (hard to get null reference exception)
- Have modules and namespaces
- Usual OOP Design Patterns = Function in F#
- Functionl (proper) and OOP
- Type Provider
Cons
- Not easy to start for usual OOP developer
- Part of .NET Framework (which is OOP and C# oriented)
- Dealing with C# - espcially "functional C#"
Action<T>
and Func<T>
- Mostly any proven library is C# based
- Abandoned by Microsoft (more emphasis on node.js and even C++)
- Part of .NET Languages
-
Lacking of Visual Studio support (as C#/node.js/C++ have)
- Some funky errors, not easy to comprehend