Hack_n_Learn_Fsharp_Ajira

 Hack_n_Learn_Fsharp_Ajira

My workshop slides for the event https://www.meetup.com/Hack-Learn/events/232941739/

C6dbbb399f7658917f60bd1e2a2663ed?s=128

Tamizhvendan S

August 27, 2016
Tweet

Transcript

  1. Let’s Learn F# Functional Programming Ahead λ

  2. About Me Pragmatic, Passionate and Polyglot Programmer @tamizhvendan http://blog.tamizhvendan.in www.ajira.tech

    bit.ly/fsapplied
  3. F# F# is a mature, open source, cross-platform, functional-first programming

    language. It empowers users and organizations to tackle complex computing problems with simple, maintainable and robust code. - http://fsharp.org/
  4. Production Ready? - http://fsharp.org/testimonials/

  5. F# ♥ - ThoughtWorks Tech Radar 2012

  6. Functional Programming x Model your domain (Data)

  7. Functional Programming λx Define functions which operate on data

  8. Functional Programming >> >=> >>= << |> Define “System” by

    composing functions
  9. POST /message Chat Server CREATE Model Your Domain HttpRequest Message

    Error Result<Message,Error> HttpResponse x
  10. 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
  11. POST /message Chat Server CREATE Compose functions readRequest >>= validate

    >>= createInDb |> writeResponse system :: HttpRequest -> HttpResponse
  12. Let’s Hack! MiniSuave A simple web development F# library https://github.com/tamizhvendan/acumen

  13. Step 1 Model HttpMethod Get, Put, Post type Color =

    Red | Green | Blue
  14. Step 2 Model Request Request contains HttpMethod & Path type

    Rectangle = { Color : Color Height : double Width : double } Whitespace is significant
  15. Step 3 Model StatusCode Ok, NotFound, BadRequest type Color =

    Red | Green | Blue
  16. Step 4 Define toStatusCode function to return StatusCode as integer

    let toHex color = match color with | Red -> "#ff0000" | Green -> "#00ff00" | Blue -> "#0000ff" Last expression is the return of the function
  17. Step 5 Model Response Response contains StatusCode & Content type

    Circle = { Color : Color Radius : double }
  18. Step 6 Model Context Context contains Request & Response type

    Shape = { Rectangle : Rectangle Circle : Circle }
  19. Step 7 Model Handler Handler takes a context and may

    return the (modified) context. type Handler = Shape -> Shape option A type can represent a function signature
  20. Step 8 Define OK Handler OK is a function that

    takes a string and a Context It modifies the Response content with the string passed and sets the status code to Ok It returns the modified context as optional type let RADIUS radius shape = let circle = { Color = Red Radius = radius } {shape with Circle = circle} Records are immutable string -> Context -> Context option
  21. Step 9 Define ConsoleWriter let ConsoleWriter ctx handler = match

    handler ctx with | Some ctx -> ctx.Response.StatusCode |> toStatusCode |> printfn "StatusCode: %d" printfn "Content : %s" ctx.Response.Content | None -> printfn "Empty"
  22. Let’s Play console (OK "test");; console <| OK "test";; fsharpi

    —use:test.fsx fsi —use:test.fsx Use #q;; to Exit
  23. Step 10 Define NOT_FOUND Handler NOT_FOUND is a function that

    takes a string and a Context It modifies the Response content with the string passed and sets the status code to NotFound It returns the modified context as optional type
  24. Step 11 Define BAD_REQUEST Handler BAD_REQUEST is a function that

    takes a string and a Context It modifies the Response content with the string passed and sets the status code to BadRequest It returns the modified context as optional type
  25. Step 12 Let’s Refactor All handlers takes a content and

    modifies the response let responseHandler statusCode content ctx = let res = {StatusCode = statusCode; Content = content} Some {ctx with Response = res} let OK = responseHandler Ok
  26. Step 13 Define GET (Filter)Handler GET verifies the HttpMethod of

    the context’s Request It returns the context if it is Get else returns None Pattern Matching against booleans Context -> Context option let SQUARE shape = let rect = shape.Rectangle match rect.Height = rect.Width with | true -> Some shape | _ -> None
  27. Step 14 Define POST (Filter)Handler POST verifies the HttpMethod of

    the context’s Request It returns the context if it is Post else returns None Context -> Context option
  28. Step 15 Define PUT (Filter)Handler PUT verifies the HttpMethod of

    the context’s Request It returns the context if it is Put else returns None Context -> Context option
  29. Step 16 Its time for Refactoring All Http Method filter

    handlers looks for a particular HttpMethod let httpMethodFilter httpMethod ctx = match ctx.Request.HttpMethod = httpMethod with | true -> Some ctx | _ -> None let GET = httpMethodFilter Get
  30. Let’s Play fsharpi —use:test.fsx fsi —use:test.fsx console GET;; console POST;;

    console PUT;;
  31. Step 17 Define Path (Filter)Handler Path takes a string in

    addition to a context. It verifies the string with the Path of the context’s Request It returns the context if it matches else returns None string -> Context -> Context option
  32. Let’s Play fsharpi —use:test.fsx fsi —use:test.fsx server "GET;/hello" (Path "/hello");;

    server "GET;/hi" (Path "/hello");; server "GET;/hi" PUT;; server "GET;/hi" GET;; server "POST;/hi" PUT;; server "POST;/hi" POST;;
  33. 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
  34. Function Composition C None Some<C> C Handler C Handler C

    f1 C C C f2 C
  35. f1 C C C f2 C C // Handler ->

    Handler -> Context -> Context option // Handler -> Handler -> Handler let compose f1 f2 ctx = match f1 ctx with | Some ctx -> f2 ctx | None -> None Step 18 Function to compose functions
  36. Step 19 Introducing Operators >=> let (>=>) = compose

  37. Let’s Play fsharpi —use:test.fsx fsi —use:test.fsx server "GET;/hello" (GET >=>

    Path "/hello" >=> OK "hello");; server "GET;/hello" (POST >=> Path "/hello" >=> OK "hello");;
  38. Step 20 Let’s Choose ! // Choose :: Handler list

    -> Context -> Context option // Choose :: Handler list -> Handler let rec fib n = match n with | 1 -> 1 | 2 -> 1 | n -> fib(n-1) + fib(n-2) let rec firstEven nums = match nums with | [] -> None | x :: xs -> match x % 2 = 0 with | true -> Some x | _ -> firstEven xs
  39. The Real Play! fsharpi —use:play.fsx fsi —use:play.fsx let handlers =

    Choose[ GET >=> Choose [ Path "/hello" >=> OK "hello" Path "/hi" >=> OK "hi" ] POST >=> Path "/hello" >=> OK "hello POST" ]
  40. https://fsharpforfunandprofit.com http://fsharp.org/ bit.ly/fsapplied