Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fsharp

 Fsharp

A two hours presentation about fsharp given at itemis Stuttgart

Kolja Dummann

August 28, 2015
Tweet

More Decks by Kolja Dummann

Other Decks in Programming

Transcript

  1. F#

  2. let x = 5 let y = 10 let z

    = x + y z = 10 Basic Syntax (Values)
  3. let addStr x y = (x + y).ToString() val addStr

    : x:int -> y:int -> string Basic Syntax (Arrow notation)
  4. let add (x : int) (y : int) = x

    + y Type inference
  5. let add (x : int) (y : int) = x

    + y let add x y = x + y Type inference
  6. let add (x : int) (y : int) = x

    + y let add x y = x + y add 5 10 Type inference
  7. let add (x : int) (y : int) = x

    + y let add x y = x + y add 5 10 add 3.14 4.56 Type inference
  8. let add (x : int) (y : int) = x

    + y let add x y = x + y add 5 10 add 3.14 4.56 add 3.14 10 Type inference
  9. let sign num = if num > 0 then "positive"

    elif num < 0 then "negative" else "zero" Type inference (more)
  10. let sign num = if num > 0 then "positive"

    elif num < 0 then "negative" else 0 Type inference (more)
  11. type IAnimal = interface… type Dog = class interface IAnimal…

    let getName (l : IAnimal) = … Type inference (more)
  12. type IAnimal = interface… type Dog = class interface IAnimal…

    let getName (l : IAnimal) = … let doStuffWithDog (d : Dog) = … Type inference (more)
  13. type IAnimal = interface… type Dog = class interface IAnimal…

    let getName (l : IAnimal) = … let doStuffWithDog (d : Dog) = … let takesStuff s = doStuffWithDog(s) getName(s) Type inference (more)
  14. let throwAwayFirstInput x y = y 'a -> 'b ->

    'b Type inference (Generics)
  15. let getPrice name = match name with | "banana" ->

    0.79 | "watermelon" -> 3.49 | "tofu" -> 1.09 | _ -> nan Pattern Matching
  16. let getPrice = function | "banana" -> 0.79 | "watermelon"

    -> 3.49 | "tofu" -> 1.09 | _ -> nan Pattern Matching
  17. let sign = function | 0 -> 0 | x

    when x < 0 -> -1 | x when x > 0 -> 1 Pattern Matching
  18. let rec fact x = if x < 1 then

    1 else x * fact (x - 1) Recursion
  19. let rec count n = if n = 1000000 then

    printfn "done" else if n % 1000 = 0 then printfn "n: %i" n count (n + 1) Recursion (Tail)
  20. let passFive f = (f 5) val passFive : (int

    -> 'a) -> 'a Higher order functions
  21. let map it converter = converter it val map :

    'a -> ('a -> 'b) -> 'b Higher order functions
  22. let add x y = x + y let addFive

    = add 5 Higher order functions
  23. let add x y = x + y val add

    : int -> int -> int let addFive = add 5 val addFive : (int -> int) Higher order functions
  24. > let div x y = x / y val

    div : int -> int -> int > div 10 5 val it : int = 2 > div 10 0 Option Types
  25. let sdiv x y = match y with | 0

    -> None | _ -> Some(x/y) val sdiv : int -> int -> int option Option Types
  26. > safediv 10 5 val it : int option =

    Some 2 > safediv 10 0 val it : int option = None Option Types
  27. let isFortyTwo = function | Some(42) -> true | Some(_)

    | None -> false > isFortyTwo (Some(43)) val it : bool = false > isFortyTwo (Some(42)) val it : bool = true Option Types
  28. > let average (a, b) = let sum = a

    + b sum / 2.0 val average : float * float -> float > average (10.0, 20.0) val it : float = 15.0 Tuples
  29. > let divrem x y = match y with |

    0 -> None | _ -> Some(x / y, x % y) val divrem : int -> int -> (int * int) option Tuples
  30. > divrem 100 20 val it : (int * int)

    option = Some (5, 0) > divrem 6 4 val it : (int * int) option = Some (1, 2) Tuples
  31. let greeting (name, language) = match (name, language) with |

    ("Steve", _) -> "Howdy, Steve" | (name, "Engl") -> "Hello, “ + name | (_, "French") -> "Bonjour!" | _ -> "DOES NOT COMPUTE" Tuples
  32. type website = { Title : string; Url : string

    } > let homepage = { Title = "Google"; Url = "http://www.google.com" } val homepage : website Records
  33. > let homepage = { Title = "Wikibooks"; Url =

    "http://www.wikibooks.org/" } val homepage : website > homepage.Title val it : string = "Wikibooks" > homepage.Url val it : string = "http://www.wikibooks.org/" Records
  34. type TransactionItem = { Name : string; ID : int;

    ProcessedText : string; IsProcessed : bool } let processItem item = { item with ProcessedText = "Done"; IsProcessed = true } Records
  35. type coords = { X : float; Y : float

    } let getQuadrant = function | { X = 0.0; Y = 0.0 } -> "Origin" | item when item.X >= 0.0 && item.Y >= 0.0 -> "I" | item when item.X <= 0.0 && item.Y >= 0.0 ->"II" | item when item.X <= 0.0 && item.Y <= 0.0 ->"III" | item when item.X >= 0.0 && item.Y <= 0.0 -> "IV" Records
  36. > let numbers = [1; 2; 3; 4; 5; 6;

    7; 8; 9; 10] val numbers : int list [1; 2; 3; 4; "cat"; 6; 7] Lists
  37. > [1 .. 10] val it : int list =

    [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] > [1 .. 2 .. 10] val it : int list = [1; 3; 5; 7; 9] > ['a' .. 's'] val it : char list Lists
  38. let rec sum total = function | [] -> total

    | hd :: tl -> sum (hd + total) tl Lists
  39. > Set.empty.Add(1).Add(2).Add(7) val it : Set<int> = set [1; 2;

    7] let a = Set.ofSeq [ 1 .. 10 ] let b = a a.Add(12) b.Add(13) Set / Map
  40. type switchstate = | On | Off let toggle =

    function | On -> Off | Off -> On let main() = let x = On let y = Off let z = toggle y Discriminated Unions
  41. > let mutable x = 5 val mutable x :

    int > x val it : int = 5 > x <- 10 val it : unit = () > x val it : int = 10 Mutability
  42. > let x = ref "hello";; val x : string

    ref > x;; (* returns ref instance *) val it : string ref = {contents = "hello";} > !x;; (* returns x.contents *) val it : string = "hello" > x := "world";; (* updates x.contents with a new value *) val it : unit = () > !x;; (* returns x.contents *) val it : string = "world" Mutability
  43. > let cell1 = ref 7;; val cell1 : int

    ref > let cell2 = cell1;; val cell2 : int ref > cell1 := 10;; val it : unit = () > !cell1;; val it : int = 10 > !cell2;; val it : int = 10 Mutability
  44. Typesafe (s)printf sprintf "Hi, I'm %s and I'm a %s"

    "Juliet" “Scorpio" sprintf "I'm %i years old" "kitty"
  45. Other Control flow: if/then, for, while Arrays: fixed size, mutable,

    fast mutable Collections/Maps Exceptions Operators: define & overload
  46. Unit of Measurement [<Measure>] type m (* meter *) [<Measure>]

    type s (* second *) [<Measure>] type kg (* kilogram *) [<Measure>] type N = (kg * m)/(s^2) (* Newtons *) [<Measure>] type Pa = N/(m^2) (* Pascals *)
  47. Unit of Measurement > let distance = 100.0<m> let time

    = 5.0<s> let speed = distance / time;; val distance : float<m> = 100.0 val time : float<s> = 5.0 val speed : float<m/s> = 20.0
  48. Unit of Measurement type triple<[<Measure>] 'a> = { a :

    float<'a>; b : float<'a>; c : float<‘a>} { a = 7.0<kg>; b = -10.5<_>; c = 0.5<_> } val it : triple<kg> = {a = 7.0; b = -10.5; c = 0.5;}
  49. Computation Expressions let read_line() = System.Console.ReadLine() let print_string(s) = printf

    "%s" s print_string "What's your name? " let name = read_line() print_string ("Hello, " + name)
  50. Computation Expressions let read_line(f) = f(System.Console.ReadLine()) let print_string(s, f) =

    f(printf "%s" s) print_string("What's your name? ", fun () -> read_line(fun name -> print_string("Hello, " + name, fun () -> () ) ) )
  51. Computation Expressions let getNum msg = printf "%s" msg match

    System.Int32.TryParse(System.Console.ReadLine()) with | (true, n) when n >= 0 && n <= 100 -> Some(n) | _ -> None match getNum "#1: " with | Some(x) -> match getNum "#2: " with | Some(y) -> match getNum "#3: " with | Some(z) -> Some(x + y + z) | None -> None | None -> None | None -> None
  52. Computation Expressions let bind(input, rest) = match System.Int32.TryParse(input()) with |

    (true, n) when n >= 0 && n <= 100 -> rest(n) | _ -> None let createMsg msg = fun () -> printf "%s" msg; System.Console.ReadLine() bind(createMsg "#1: ", fun x -> bind(createMsg "#2: ", fun y -> bind(createMsg "#3: ", fun z -> Some(x + y + z) ) ) )
  53. Computation Expressions let bind(input, rest) = rest(input()) let download (url

    : string) = bind( (fun () -> new System.Net.WebClient()), fun webclient -> bind( (fun () -> webclient.DownloadString(url)), fun html -> bind( (fun () -> Regex.Matches(html, @"http://\S+") ), fun matches -> printMsg ("Found " + matches.Count.ToString() + " links") ) ) ) ["http://www.google.com/"; "http://microsoft.com/"; "http://www.wordpress.com/"; "http://www.peta.org"] |> Seq.iter download
  54. Computation Expressions let bind(input, rest) = ThreadPool.QueueUserWorkItem(new WaitCallback(fun _ ->

    rest(input()))) let download (url : string) = bind( (fun () -> new System.Net.WebClient()), fun webclient -> bind( (fun () -> webclient.DownloadString(url)), fun html -> bind( (fun () -> Regex.Matches(html, @"http://\S+") ), fun matches -> printMsg ("Found " + matches.Count.ToString() + " links") ) ) ) ["http://www.google.com/"; "http://microsoft.com/"; "http://www.wordpress.com/"; "http://www.peta.org"] |> Seq.iter download
  55. Computation Expressions let bind(input, rest) = match System.Int32.TryParse(input()) with |

    (true, n) when n >= 0 && n <= 100 -> rest(n) | _ -> None let createMsg msg = fun () -> printf "%s" msg; System.Console.ReadLine() bind(createMsg "#1: ", fun x -> bind(createMsg "#2: ", fun y -> bind(createMsg "#3: ", fun z -> Some(x + y + z) ) ) )
  56. Computation Expressions > type MaybeBuilder() = member this.Bind(x, f) =

    printfn "this.Bind: %A" x match x with | Some(x) when x >= 0 && x <= 100 -> f(x) | _ -> None member this.Delay(f) = f() member this.Return(x) = Some x
  57. Computation Expressions let maybe = new MaybeBuilder() let sugared =

    maybe { let x = 12 let! y = Some 11 let! z = Some 30 return x + y + z }
  58. Computation Expressions let maybe = new MaybeBuilder() let desugared =

    maybe.Delay(fun () -> let x = 12 maybe.Bind(Some 11, fun y -> maybe.Bind(Some 30, fun z -> maybe.Return(x + y + z) ) ) )
  59. Async Workflows let extractLinks url = async { let webClient

    = new System.Net.WebClient() printfn "Downloading %s" url let html = webClient.DownloadString(url : string) printfn "Got %i bytes" html.Length let matches = Regex.Matches(html, @"http://\S+") printfn "Got %i links" matches.Count return url, matches.Count };;
  60. Mailboxes type msg = | Incr of int | Fetch

    of AsyncReplyChannel<int> let counter = MailboxProcessor.Start(fun inbox -> let rec loop n = async { let! msg = inbox.Receive() match msg with | Incr(x) -> return! loop(n + x) | Fetch(replyChannel) -> replyChannel.Reply(n) return! loop(n) } loop 0)
  61. Mailboxes > counter.Post(Incr 7);; val it : unit = ()

    > counter.Post(Incr 50);; val it : unit = () > counter.PostAndReply(fun replyChannel -> Fetch replyChannel);; val it : int = 57