Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

My adventure with elm (LambdaCon15)

2,446 views

Published on

Published in: Technology
  • Be the first to comment

My adventure with elm (LambdaCon15)

  1. 1. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  2. 2. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon agenda
  3. 3. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Hi, my name isYan Cui.
  4. 4. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  5. 5. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon I’m not an expert on Elm.
  6. 6. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  7. 7. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Function Reactive Programming?
  8. 8. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Value over Time
  9. 9. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value
  10. 10. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value Signal
  11. 11. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  12. 12. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ?
  13. 13. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  14. 14. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  15. 15. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon SignalVariable
  16. 16. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  17. 17. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  18. 18. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive is Dead, long live composing side effects. bit.ly/1sb5hCu
  19. 19. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  20. 20. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon In computing, reactive programming is a programming paradigm oriented around data flows and the propagation of change.This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow.
  21. 21. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  22. 22. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Scalable ResilientReplication High-Availability Elasticity Non-Blocking Asynchronous Message-Passing Isolation Containment Location-Transparency Loose-Coupling
  23. 23. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive Programming =
  24. 24. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon bit.ly/1sb5hCu Reactive is Dead, long live composing side effects.
  25. 25. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon “One thing I’m discovering is that transforming data is easier to think about than maintaining state.” ! - Dave Thomas
  26. 26. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon let y = f(x) Imperative Functional x.f()
  27. 27. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon mutation let y = f(x) Imperative Functional x.f()
  28. 28. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  29. 29. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  30. 30. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon private var arrowKeyUp:Bool; private var arrowKeyDown:Bool; ! private var platform1:Platform; private var platform2:Platform; private var ball:Ball;
  31. 31. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon function keyDown(event:KeyboardEvent):Void { if (currentGameState == Paused && event.keyCode == 32) { setGameState(Playing); } else if (event.keyCode == 38) { arrowKeyUp = true; } else if (event.keyCode == 40) { arrowKeyDown = true; } }
  32. 32. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon function keyUp(event:KeyboardEvent):Void { if (event.keyCode == 38) { arrowKeyUp = false; } else if (event.keyCode == 40) { arrowKeyDown = false; } }
  33. 33. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }
  34. 34. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }
  35. 35. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files state changes
  36. 36. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  37. 37. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  38. 38. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon mental model input state new state behaviour { x; y } { x; y-speed } { x; y } { x; y+speed } timer { x; y } { x; y } draw platform … … … …
  39. 39. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon transformation let y = f(x) Imperative Functional x.f()
  40. 40. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Transformations simplify problem decomposition
  41. 41. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  42. 42. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  43. 43. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  44. 44. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  45. 45. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon UP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }
  46. 46. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  47. 47. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  48. 48. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  49. 49. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  50. 50. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} ! delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows ! cap x = max 5 <| min x 395 ! p1 : Signal Platform p1 = foldp ({x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
  51. 51. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Rx Dart Elm Observable Stream Signal = =
  52. 52. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  53. 53. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  54. 54. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  55. 55. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Idea See in Action
  56. 56. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  57. 57. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  58. 58. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  59. 59. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon http://bit.ly/1wV46XS
  60. 60. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Elm Basics
  61. 61. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add x y = x + y
  62. 62. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add : Int -> Int -> Int add x y = x + y
  63. 63. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH
  64. 64. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH
  65. 65. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH
  66. 66. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  67. 67. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  68. 68. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon f a b c d = … f : Int -> (Int -> (Int -> (Int -> Int)))
  69. 69. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map (x -> x * 2) list
  70. 70. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map ((*) 2) list
  71. 71. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple1 = (2,“three”) tuple2 = (2,“three”, [4, 5])
  72. 72. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple4 = (,) 2 “three” tuple5 = (,,) 2 “three” [4, 5]
  73. 73. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x = { age=42, name=“foo” }
  74. 74. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lightweight, labelled data structure
  75. 75. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo”
  76. 76. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo” .age x .name x -- 42 -- “foo”
  77. 77. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon -- clone and update y = { x | name <- "bar" }
  78. 78. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Character = { age : Int, name : String }
  79. 79. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Named a = { a | name : String } type alias Aged a = { a | age : Int }
  80. 80. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lady : Named ( Aged { } ) lady = { name=“foo”, age=42 }
  81. 81. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name
  82. 82. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name ! getName lady -- “foo”
  83. 83. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type Status = Flying Pos Speed | Exploding Radius | Exploded
  84. 84. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon aka. “sums-and-products” data structures
  85. 85. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type Status = Flying Pos Speed | Exploding Radius | Exploded sums : choice between variants of a type
  86. 86. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon products : tuple of types type Status = Flying Pos Speed | Exploding Radius | Exploded
  87. 87. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
  88. 88. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) filled : Color -> Shape -> Form
  89. 89. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
  90. 90. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
  91. 91. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon “…a clean design is one that supports visual thinking so people can meet their informational needs with a minimum of conscious effort.” ! - Daniel Higginbotham (www.visualmess.com)
  92. 92. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  93. 93. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = radius |> circle |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) 2.top-to-bottom 1. left-to-right
  94. 94. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> Float -> Form
  95. 95. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = circle >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  96. 96. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = circle >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) circle : Float -> Shape
  97. 97. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  98. 98. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) filled : Color -> Shape -> Form
  99. 99. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) Curried! filled : Color -> Shape -> Form
  100. 100. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) Shape -> Form
  101. 101. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  102. 102. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  103. 103. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  104. 104. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  105. 105. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> alpha 0.5 >> move (x, y)
  106. 106. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  107. 107. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  108. 108. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> move (x, y)
  109. 109. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  110. 110. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  111. 111. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form)
  112. 112. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> (Float -> Form)
  113. 113. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  114. 114. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  115. 115. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon fizzbuzz n = if | n % 15 == 0 -> "fizz buzz" | n % 3 == 0 -> "fizz" | n % 5 == 0 -> "buzz" | otherwise -> show n
  116. 116. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position Mouse.clicks Mouse.isDown …
  117. 117. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Window.dimension Window.width Window.height
  118. 118. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time.every Time.fps Time.timestamp Time.delay …
  119. 119. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  120. 120. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  121. 121. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int) (10, 23) (3, 16) (8, 10) (12, 5) (18, 3)
  122. 122. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int
  123. 123. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int H E L L O space
  124. 124. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int H E L L O space 72 69 76 76 79 32
  125. 125. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map : (a -> b) -> Signal a -> Signal b
  126. 126. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon <~
  127. 127. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Signal of num of pixels in window
  128. 128. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions
  129. 129. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int
  130. 130. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int Signal Int
  131. 131. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (10, 10) (15, 10) (18, 12) 100 150 216 ((w, h) -> w*h) <~ Window.dimensions
  132. 132. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map2 : (a -> b -> c) -> Signal a -> Signal b -> Signal c
  133. 133. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ~
  134. 134. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int a -> b -> (a, b) Signal Int
  135. 135. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int Int -> Int -> (Int, Int) Signal Int
  136. 136. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map3 : (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
  137. 137. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,,) <~ signalA ~ signalB ~ signalC
  138. 138. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map4 : … map5 : … map6 : … map7 : … map8 : …
  139. 139. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  140. 140. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  141. 141. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  142. 142. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  143. 143. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  144. 144. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  145. 145. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  146. 146. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  147. 147. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  148. 148. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 1 3 42 5 foldp (_ n -> n + 1) 0 Mouse.clicks
  149. 149. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon UP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }
  150. 150. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon merge : Signal a -> Signal a -> Signal a mergeMany : List (Signal a) -> Signal a …
  151. 151. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Js Interop, WebGL HTML layout, dependency management, etc.
  152. 152. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  153. 153. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 8 segments
  154. 154. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  155. 155. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon change change no changenot allowed direction
  156. 156. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  157. 157. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  158. 158. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  159. 159. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  160. 160. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction cherry
  161. 161. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction YUMYUMYUM!
  162. 162. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction +1 segment
  163. 163. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  164. 164. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  165. 165. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  166. 166. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  167. 167. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  168. 168. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  169. 169. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Demo
  170. 170. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  171. 171. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  172. 172. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  173. 173. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  174. 174. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  175. 175. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  176. 176. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  177. 177. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  178. 178. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  179. 179. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  180. 180. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  181. 181. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  182. 182. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  183. 183. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  184. 184. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  185. 185. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  186. 186. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon github.com/theburningmonk/elm-snake github.com/theburningmonk/elm-missile- command Missile Command Snake
  187. 187. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon elm-lang.org/try debug.elm-lang.org/try
  188. 188. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon the

×