SlideShare ist ein Scribd-Unternehmen logo
1 von 199
Downloaden Sie, um offline zu lesen
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
agenda
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Hi, my name isYan Cui.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
I’m not an expert on Elm.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Function Reactive
Programming?
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Value over Time
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time
Value
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time
Value
Signal
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
?
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
SignalVariable
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Reactive is Dead,	

long live composing side effects.
bit.ly/1sb5hCu
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
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.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Scalable
ResilientReplication
High-Availability
Elasticity
Non-Blocking
Asynchronous
Message-Passing
Isolation
Containment
Location-Transparency
Loose-Coupling
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Reactive Programming =
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
bit.ly/1sb5hCu
Reactive is Dead,	

long live composing side effects.
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
mutation
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Move Up
Move Down
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;
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;
	

 }	

}
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;
	

 }	

}
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;	

	

 }	

}
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;
	

 }	

}
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files
state changes
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files execution
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files execution
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
… … … …
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
transformation
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Transformations
simplify problem
decomposition
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Move Up
Move Down
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
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
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
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 }
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
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
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Rx Dart Elm
Observable Stream Signal
= =
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Idea See in Action
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
http://bit.ly/1wV46XS
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Elm Basics
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
add x y = x + y
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
add : Int -> Int -> Int
add x y = x + y
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
multiply x y	

= x * y	

triple = multiply 3
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
multiply x y	

= x * y	

triple = multiply 3
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
f a b c d = …	

f :	

 Int -> 	

	

 	

 	

 (Int -> 	

	

 	

 	

 	

 (Int -> 	

	

 	

 	

 	

 	

 (Int -> Int)))
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
double list = List.map (x -> x * 2) list
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
double list = List.map ((*) 2) list
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
tuple1 = (2,“three”)	

tuple2 = (2,“three”, [4, 5])
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
tuple4 = (,) 2 “three”	

tuple5 = (,,) 2 “three” [4, 5]
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x = { age=42, name=“foo” }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
lightweight, labelled
data structure
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x.age	

x.name
-- 42	

-- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x.age	

x.name
-- 42	

-- “foo”
.age x	

.name x
-- 42	

-- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
-- clone and update	

y = { x | name <- "bar" }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type alias Character = 	

{ age : Int, name : String }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type alias Named a = { a | name : String }	

type alias Aged a = { a | age : Int }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
lady : Named ( Aged { } )	

lady = { name=“foo”, age=42 }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
getName : Named x -> String	

getName { name } = name
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
getName : Named x -> String	

getName { name } = name	

!
getName lady	

	

 -- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 	

 | Exploded
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
aka.	

“sums-and-products”	

data structures
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 | Exploded
sums : 	

choice between variants of a type
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
products : 	

tuple of types
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 | Exploded
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)
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
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)
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)
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)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle : Int -> Int -> Float -> Form
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 circle 	

	

>> filled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> filled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form)	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle : Int -> Int -> (Float -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
greet name =	

case name of 	

"Yan" 	

-> “hi, theburningmonk"	

_ 	

	

 -> “hi,“ ++ name
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
greet name =	

case name of 	

"Yan" 	

-> “hi, theburningmonk"	

_ 	

	

 -> “hi,“ ++ name
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position	

Mouse.clicks	

Mouse.isDown	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Window.dimension	

Window.width	

Window.height
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time.every	

Time.fps	

Time.timestamp	

Time.delay	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
(10, 23) (3, 16) (8, 10) (12, 5) (18, 3)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
H E L L O space
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
H E L L O space
72 69 76 76 79 32
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map : (a -> b) -> Signal a -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
<~
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Signal of num of pixels in window
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
Signal (Int, Int)(Int, Int) -> Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
Signal (Int, Int)(Int, Int) -> Int
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(10, 10) (15, 10) (18, 12)
100 150 216
((w, h) -> w*h) <~ Window.dimensions
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map2 : (a -> b -> c) 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b 	

	

 	

 	

 	

 -> Signal c
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
~
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,) <~ Window.width ~ Window.height
Signal Int
a -> b -> (a, b)
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,) <~ Window.width ~ Window.height
Signal Int
Int -> Int -> (Int, Int)
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map3 : (a -> b -> c -> d) 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b 	

	

 	

 	

 	

 -> Signal c	

	

 	

 	

 	

 -> Signal d
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,,) <~ signalA ~ signalB ~ signalC
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map4 : …	

map5 : …	

map6 : …	

map7 : …	

map8 : …
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b
	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b
	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
1 3 42 5
foldp (_ n -> n + 1) 0 Mouse.clicks
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 }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
merge	

 : Signal a -> Signal a -> Signal a	

mergeMany : List (Signal a) -> Signal a	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Js Interop,
WebGL
HTML layout,
dependency management,
etc.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
8 segments
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
change
change
no changenot allowed
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
cherry
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
YUMYUMYUM!
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
+1 segment
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Demo
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
github.com/theburningmonk/elm-snake
github.com/theburningmonk/elm-missile-
command
Missile Command
Snake
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
elm-lang.org/try
debug.elm-lang.org/try
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
the
 not
 so
 great
 things
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Type error between lines 63 and 85:	

case gameState of	

NotStarted - if | userInput == Space -	

Started (defaultSnake,Nothing)	

| True - gameState	

Started ({segments,direction},cherry) - let arrow = case userInput	

of	

Arrow arrow - arrow	

_ - {x = 0, y = 0}	

newDirection = getNewDirection	

arrow direction	

newHead = getNewSegment	

(List.head segments) newDirection	

newTail = List.take	

((List.length segments) - 1)	

segments	

(w,h) = windowDims	

isGameOver = (List.any	

(t - t == newHead)	

newTail) ||	

(((fst newHead) 	

((toFloat w) / 2)) ||	

(((snd newHead) 	

((toFloat h) / 2)) ||	

(((fst newHead) 	

((toFloat (-w)) / 2)) ||	

((snd newHead) 	

((toFloat (-h)) / 2)))))	

in if | isGameOver - NotStarted	

| True -	

Started	

({segments = newHead :: newTail,	

direction = newDirection},	

cherry)	

!
Expected Type: {}	

Actual Type: Snake.Input
cryptic error
messages
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
breaking changes
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Weitere ähnliche Inhalte

Mehr von Yan Cui

How to choose the right messaging service for your workload
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workloadYan Cui
 
Patterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfYan Cui
 
Lambda and DynamoDB best practices
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practicesYan Cui
 
Lessons from running AppSync in prod
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prodYan Cui
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspectiveYan Cui
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functionsYan Cui
 
How serverless changes the cost paradigm
How serverless changes the cost paradigmHow serverless changes the cost paradigm
How serverless changes the cost paradigmYan Cui
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncYan Cui
 
Build social network in 4 weeks
Build social network in 4 weeksBuild social network in 4 weeks
Build social network in 4 weeksYan Cui
 
Patterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsPatterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsYan Cui
 
How to bring chaos engineering to serverless
How to bring chaos engineering to serverlessHow to bring chaos engineering to serverless
How to bring chaos engineering to serverlessYan Cui
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsYan Cui
 
Building a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLBuilding a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLYan Cui
 
FinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyFinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyYan Cui
 
How to improve lambda cold starts
How to improve lambda cold startsHow to improve lambda cold starts
How to improve lambda cold startsYan Cui
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020Yan Cui
 
A chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayA chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayYan Cui
 
How to debug slow lambda response times
How to debug slow lambda response timesHow to debug slow lambda response times
How to debug slow lambda response timesYan Cui
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020Yan Cui
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functionsYan Cui
 

Mehr von Yan Cui (20)

How to choose the right messaging service for your workload
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workload
 
Patterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdf
 
Lambda and DynamoDB best practices
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practices
 
Lessons from running AppSync in prod
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prod
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspective
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
 
How serverless changes the cost paradigm
How serverless changes the cost paradigmHow serverless changes the cost paradigm
How serverless changes the cost paradigm
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSync
 
Build social network in 4 weeks
Build social network in 4 weeksBuild social network in 4 weeks
Build social network in 4 weeks
 
Patterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsPatterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applications
 
How to bring chaos engineering to serverless
How to bring chaos engineering to serverlessHow to bring chaos engineering to serverless
How to bring chaos engineering to serverless
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 steps
 
Building a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLBuilding a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQL
 
FinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyFinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economy
 
How to improve lambda cold starts
How to improve lambda cold startsHow to improve lambda cold starts
How to improve lambda cold starts
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020
 
A chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayA chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage away
 
How to debug slow lambda response times
How to debug slow lambda response timesHow to debug slow lambda response times
How to debug slow lambda response times
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
 

Kürzlich hochgeladen

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 

Kürzlich hochgeladen (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 

My adventure with elm (LambdaCon15)

  • 1. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 2. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon agenda
  • 3. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Hi, my name isYan Cui.
  • 4. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 5. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon I’m not an expert on Elm.
  • 6. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 7. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Function Reactive Programming?
  • 8. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Value over Time
  • 9. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value
  • 10. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value Signal
  • 11. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 12. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ?
  • 13. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 14. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 15. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon SignalVariable
  • 16. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 17. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 18. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive is Dead, long live composing side effects. bit.ly/1sb5hCu
  • 19. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive Programming =
  • 24. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon bit.ly/1sb5hCu Reactive is Dead, long live composing side effects.
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon let y = f(x) Imperative Functional x.f()
  • 27. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon mutation let y = f(x) Imperative Functional x.f()
  • 28. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 29. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  • 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. 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. 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. 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. 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files state changes
  • 36. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  • 37. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon transformation let y = f(x) Imperative Functional x.f()
  • 40. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Transformations simplify problem decomposition
  • 41. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Rx Dart Elm Observable Stream Signal = =
  • 52. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 53. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 54. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 55. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Idea See in Action
  • 56. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 57. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 58. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 59. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon http://bit.ly/1wV46XS
  • 60. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Elm Basics
  • 61. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add x y = x + y
  • 62. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add : Int -> Int -> Int add x y = x + y
  • 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. 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. 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  • 67. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  • 68. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon f a b c d = … f : Int -> (Int -> (Int -> (Int -> Int)))
  • 69. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map (x -> x * 2) list
  • 70. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map ((*) 2) list
  • 71. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple1 = (2,“three”) tuple2 = (2,“three”, [4, 5])
  • 72. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple4 = (,) 2 “three” tuple5 = (,,) 2 “three” [4, 5]
  • 73. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x = { age=42, name=“foo” }
  • 74. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lightweight, labelled data structure
  • 75. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo”
  • 76. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo” .age x .name x -- 42 -- “foo”
  • 77. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon -- clone and update y = { x | name <- "bar" }
  • 78. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Character = { age : Int, name : String }
  • 79. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Named a = { a | name : String } type alias Aged a = { a | age : Int }
  • 80. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lady : Named ( Aged { } ) lady = { name=“foo”, age=42 }
  • 81. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name
  • 82. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name ! getName lady -- “foo”
  • 83. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type Status = Flying Pos Speed | Exploding Radius | Exploded
  • 84. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon aka. “sums-and-products” data structures
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon products : tuple of types type Status = Flying Pos Speed | Exploding Radius | Exploded
  • 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. 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. 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. 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. 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> Float -> Form
  • 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. 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. 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. 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. 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. 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 102. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 103. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 104. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 105. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> alpha 0.5 >> move (x, y)
  • 106. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  • 107. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  • 108. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> move (x, y)
  • 109. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  • 110. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  • 111. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form)
  • 112. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> (Float -> Form)
  • 113. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  • 114. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position Mouse.clicks Mouse.isDown …
  • 117. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Window.dimension Window.width Window.height
  • 118. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time.every Time.fps Time.timestamp Time.delay …
  • 119. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  • 120. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int
  • 123. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int H E L L O space
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map : (a -> b) -> Signal a -> Signal b
  • 126. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon <~
  • 127. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Signal of num of pixels in window
  • 128. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions
  • 129. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int
  • 130. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int Signal Int
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map2 : (a -> b -> c) -> Signal a -> Signal b -> Signal c
  • 133. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ~
  • 134. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int a -> b -> (a, b) Signal Int
  • 135. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int Int -> Int -> (Int, Int) Signal Int
  • 136. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map3 : (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
  • 137. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,,) <~ signalA ~ signalB ~ signalC
  • 138. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map4 : … map5 : … map6 : … map7 : … map8 : …
  • 139. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 140. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 141. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 142. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 143. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 144. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 145. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 146. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 147. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 148. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 1 3 42 5 foldp (_ n -> n + 1) 0 Mouse.clicks
  • 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. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon merge : Signal a -> Signal a -> Signal a mergeMany : List (Signal a) -> Signal a …
  • 151. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Js Interop, WebGL HTML layout, dependency management, etc.
  • 152. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 153. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 8 segments
  • 154. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 155. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon change change no changenot allowed direction
  • 156. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 157. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 158. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 159. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 160. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction cherry
  • 161. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction YUMYUMYUM!
  • 162. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction +1 segment
  • 163. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 164. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 165. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 166. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 167. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 168. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 169. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Demo
  • 170. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 171. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 172. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 173. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 174. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 175. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 176. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 177. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 178. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 179. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 180. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 181. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 182. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 183. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 184. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 185. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 186. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon github.com/theburningmonk/elm-snake github.com/theburningmonk/elm-missile- command Missile Command Snake
  • 187. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon elm-lang.org/try debug.elm-lang.org/try
  • 188. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon the
  • 189.  not
  • 190.  so
  • 193. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Type error between lines 63 and 85: case gameState of NotStarted - if | userInput == Space - Started (defaultSnake,Nothing) | True - gameState Started ({segments,direction},cherry) - let arrow = case userInput of Arrow arrow - arrow _ - {x = 0, y = 0} newDirection = getNewDirection arrow direction newHead = getNewSegment (List.head segments) newDirection newTail = List.take ((List.length segments) - 1) segments (w,h) = windowDims isGameOver = (List.any (t - t == newHead) newTail) || (((fst newHead) ((toFloat w) / 2)) || (((snd newHead) ((toFloat h) / 2)) || (((fst newHead) ((toFloat (-w)) / 2)) || ((snd newHead) ((toFloat (-h)) / 2))))) in if | isGameOver - NotStarted | True - Started ({segments = newHead :: newTail, direction = newDirection}, cherry) ! Expected Type: {} Actual Type: Snake.Input cryptic error messages
  • 194. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon breaking changes
  • 195. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 196. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 197. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 198. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 199. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 200. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 201. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 202. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon @theburningmonk github.com/theburningmonk theburningmonk.com
  • 203. Leave your feedback on Joind.in! https://joind.in/13665 ! ! BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon