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

Getting Started in Functional Programming using F#

Getting Started in Functional Programming using F#

Solving complex problems with less code is the beauty of functional programming. But for programmers who are coming from imperative or object-oriented programming background, it is very hard to think from a different perspective and follow the design principles of functional programming.

Functional Programming is not as hard as you think. This talk will help you to demystify the perceived complexities of functional programming and empower you to get started in functional programming using F#.

Meetup: http://www.meetup.com/Chennai-Microsoft-Azure-User-Group/events/235035148/

Tamizhvendan S

November 19, 2016
Tweet

More Decks by Tamizhvendan S

Other Decks in Programming

Transcript

  1. POST /message Chat Server CREATE Define functions readRequest :: HttpRequest

    -> Result<Message,Error> validate :: Message -> Result<Message,Error> λx
  2. POST /message Chat Server CREATE Define functions readRequest :: HttpRequest

    -> Result<Message,Error> validate :: Message -> Result<Message,Error> createInDb :: Message -> Result<Message,Error> λx
  3. POST /message Chat Server CREATE Define functions readRequest :: HttpRequest

    -> Result<Message,Error> validate :: Message -> Result<Message,Error> createInDb :: Message -> Result<Message,Error> writeResponse :: Result<Message,Error> -> HttpResponse λx
  4. POST /message Chat Server CREATE Compose functions readRequest system ::

    HttpRequest -> HttpResponse >>= validate >>= createInDb |> writeResponse
  5. Domain User sends a Request and gets a Response after

    some time Request contains HttpMethod, Headers & a Resource Path HttpMethod will be any one of Get, Post, Put, Delete Headers is a list of Key Value pairs Path specifies the path of the resource being requested
  6. Domain Response contains StatusCode, Headers & Content StatusCode will be

    any one of Ok, NotFound, BadRequest Headers is a list of Key Value pairs Content represents resource that is requested.
  7. type Request = { Path : string Headers : Header

    list HttpMethod : HttpMethod }
  8. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res
  9. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res
  10. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res
  11. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res
  12. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res >>
  13. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res >>
  14. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res >>
  15. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res >> x
  16. Design For Composition x f1 y y f2 z >>

    x f1 >> f2 z req handler1 res req handler2 res >> x Create a new type containing Request & Response
  17. C handler1 C C handler2 C If handler1 handle the

    req don’t invoke handler2 Choose either one of the handler Invoke handler2 always Design For Composition
  18. Combinator Pattern type WebPart = Context -> Async<Context option> The

    application is a list of WebParts Combined together in some order
  19. Combinator Pattern type WebPart = Context -> Async<Context option> functions

    that create WebPart The application is a list of WebParts Combined together in some order
  20. Combinator Pattern type WebPart = Context -> Async<Context option> functions

    that create WebPart The application is a list of WebParts Combined together in some order functions that combine WebParts
  21. Combinators type WebPart = Context -> Async<Context option> functions that

    create WebPart combinator<‘a> : ‘a -> WebPart
  22. Define OK Combinator OK is a combinator that takes a

    string and returns a WebPart It modifies the Response’s Content field with the string passed and sets its StatusCode field to Ok Then it asynchronously returns the modified context as Optional type string -> WebPart string -> Context -> Async<Context option>
  23. let OK content ctx = let response = {ctx.Response with

    StatusCode = Ok Content = content} {ctx with Response = response} |> Some |> async.Return
  24. Define NOT_FOUND Combinator NOT_FOUND is a combinator that takes a

    string and returns a WebPart It modifies the Response’s Content field with the string passed and sets its StatusCode field to NotFound Then it asynchronously returns the modified context as Optional type string -> WebPart string -> Context -> Async<Context option>
  25. let NOT_FOUND content ctx = let response = {ctx.Response with

    StatusCode = NotFound Content = content} {ctx with Response = response} |> Some |> async.Return
  26. Define BAD_REQUEST Combinator BAD_REQUEST is a combinator that takes a

    string and returns a WebPart It modifies the Response’s Content field with the string passed and sets its StatusCode field to BadRequest Then it asynchronously returns the modified context as Optional type string -> WebPart string -> Context -> Async<Context option>
  27. let BAD_REQUEST content ctx = let response = {ctx.Response with

    StatusCode = BadRequest Content = content} {ctx with Response = response} |> Some |> async.Return
  28. Define GET Filter GET verifies the HttpMethod of the context’s

    Request It asynchronously returns the context as Optional Type, if it is Get else asynchronously returns None Context -> Async<Context option>
  29. let GET ctx = match ctx.Request.HttpMethod = Get with |

    true -> Some ctx |> async.Return | _ -> None |> async.Return
  30. Define POST Filter POST verifies the HttpMethod of the context’s

    Request It asynchronously returns the context as Optional Type, if it is Post else asynchronously returns None Context -> Async<Context option>
  31. let POST ctx = match ctx.Request.HttpMethod = Post with |

    true -> Some ctx |> async.Return | _ -> None |> async.Return
  32. Define PUT Filter PUT verifies the HttpMethod of the context’s

    Request It asynchronously returns the context as Optional Type, if it is Put else asynchronously returns None Context -> Async<Context option>
  33. let PUT ctx = match ctx.Request.HttpMethod = Put with |

    true -> Some ctx |> async.Return | _ -> None |> async.Return
  34. Define DELETE Filter DELETE verifies the HttpMethod of the context’s

    Request It asynchronously returns the context as Optional Type, if it is Delete else asynchronously returns None Context -> Async<Context option>
  35. let DELETE ctx = match ctx.Request.HttpMethod = Delete with |

    true -> Some ctx |> async.Return | _ -> None |> async.Return
  36. Define Path Filter Path takes a string and verifies it

    for equality with the Path of the context’s Request It asynchronously returns the context as Optional Type, if the path matches else asynchronously returns None string -> Context -> Context option
  37. let Path path ctx = match ctx.Request.Path = path with

    | true -> ctx |> Some |> async.Return | _ -> None |> async.Return
  38. Function Composition x f1 y y f2 z >> x

    f1 >> f2 z x f1 y y f2 z >>x f1 >> f2 >> f3 z z f3 a
  39. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> C C WebPart C C WebPart
  40. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> C C WebPart C C WebPart C WebPart C
  41. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> C C WebPart C C WebPart C WebPart C C WebPart C
  42. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> C C WebPart C C WebPart C WebPart C C WebPart C C WebPart C
  43. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> >> C C WebPart C C WebPart C WebPart C C WebPart C C WebPart C
  44. Function Composition Async<None> Async<Some<C>> C Some<C> None type WebPart =

    Context -> Async<Context option> >> C C WebPart C C WebPart C WebPart C C WebPart C C WebPart C
  45. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  46. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  47. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  48. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  49. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  50. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously
  51. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously C
  52. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously C
  53. Async in F# // Async<int> let count = async.Return 5

    let count = async {return 5} // Async<int> -> Async<uint> let printAsync asyncContent = async { let! content = asyncContent printfn "%d" content } // calling async functions printAsync count |> Async.RunSynchronously C C
  54. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven
  55. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven
  56. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C
  57. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C
  58. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  59. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  60. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  61. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  62. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  63. Option in F# // int option let age = Some

    25 let ageNotGiven = None // int option -> unit let printOption value = match value with | Some v -> printfn "%d" v | None -> printfn "<EMPTY>" printOption age printOption ageNotGiven C C
  64. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts
  65. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts
  66. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts OK C C content string -> Context -> Async<Context option>
  67. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts OK C C content string -> Context -> Async<Context option> function that create WebPart
  68. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts OK C C content string -> Context -> Async<Context option> compose C C w1 w2 WebPart -> WebPart -> Context -> Async<Context option> function that create WebPart
  69. >=> C w1 C C w2 C C w1 type

    WebPart = Context -> Async<Context option> Composing WebParts OK C C content string -> Context -> Async<Context option> compose C C w1 w2 WebPart -> WebPart -> Context -> Async<Context option> function that create WebPart function that combine WebParts
  70. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx }
  71. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } Let’s go inside compose
  72. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } Let’s go inside compose
  73. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } let! result = w1 ctx Let’s go inside compose
  74. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } let! result = w1 ctx C w1 C Let’s go inside compose
  75. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } let! result = w1 ctx C w1 C Let’s go inside compose
  76. compose C C w1 w2 let compose w1 w2 ctx

    = async { return Some ctx } let! result = w1 ctx C w1 C C Let’s go inside compose
  77. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx return Some ctx } C w1 C C
  78. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx return Some ctx } C w1 C C
  79. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx return Some ctx } C w1 C C match result with | Some c -> () | None -> ()
  80. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx return Some ctx } C w1 C C match result with | Some c -> () | None -> () C C
  81. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C
  82. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C
  83. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C let! result = w2 c return result return None
  84. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C let! result = w2 c return result return None w2 C
  85. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C let! result = w2 c return result return None w2 C let compose w1 w2 ctx = async { let! result = w1 ctx match result with | Some c -> | None -> return None }
  86. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C let! result = w2 c return result return None w2 C let compose w1 w2 ctx = async { let! result = w1 ctx match result with | Some c -> | None -> return None }
  87. compose C C w1 w2 let compose w1 w2 ctx

    = async { let! result = w1 ctx match result with | Some c -> | None -> } C w1 C C C C let! result = w2 c return result return None w2 C let compose w1 w2 ctx = async { let! result = w1 ctx match result with | Some c -> | None -> return None } return! w2 c
  88. Define compose Function WebPart -> WebPart -> Context -> Async<Context

    option> compose function takes two web parts and compose it together
  89. compose function is in turn composable! WebPart -> WebPart ->

    Context -> Async<Context option> WebPart -> WebPart -> WebPart
  90. compose function is in turn composable! WebPart -> WebPart ->

    Context -> Async<Context option> WebPart -> WebPart -> WebPart
  91. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx
  92. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { }
  93. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { }
  94. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs ->
  95. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs ->
  96. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx
  97. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx
  98. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx match result with | Some c -> return Some c | None -> return! Choose xs ctx
  99. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx match result with | Some c -> return Some c | None -> return! Choose xs ctx
  100. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx match result with | Some c -> return Some c | None -> return! Choose xs ctx
  101. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx match result with | Some c -> return Some c | None -> return! Choose xs ctx
  102. Let’s Choose ! WebPart list -> Context -> Async<Context option>

    Choose function takes a list of web parts and returns the first one that matches the request λx let rec Choose webparts ctx = async { } match webparts with | [] -> return None | x :: xs -> let! result = x ctx match result with | Some c -> return Some c | None -> return! Choose xs ctx