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 ïŹ‚ows and the
propagation of change.This means that it should be
possible to express static or dynamic data ïŹ‚ows with
ease in the programming languages used, and that the
underlying execution model will automatically
propagate changes through the data ïŹ‚ow.
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 ïŹles
state changes
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source ïŹles execution
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source ïŹles 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	

	

|> ïŹlled (rgb 150 170 150)	

	

 |> alpha 0.5	

	

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

	

 circle radius	

	

|> ïŹlled (rgb 150 170 150)	

	

 |> alpha 0.5	

	

 |> move (x, y)	

ïŹlled : Color -> Shape -> Form
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y radius =	

	

 circle radius	

	

|> ïŹlled (rgb 150 170 150)	

	

 |> alpha 0.5	

	

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

	

 circle radius	

	

|> ïŹlled (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	

	

|> ïŹlled (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 	

	

>> ïŹlled (rgb 150 170 150)	

	

>> alpha 0.5	

	

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

	

 circle 	

	

>> ïŹlled (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) 	

	

>> ïŹlled (rgb 150 170 150)	

	

>> alpha 0.5	

	

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

	

 (Float -> Shape) 	

	

>> ïŹlled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
ïŹlled : Color -> Shape -> Form
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> ïŹlled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
Curried!
ïŹlled : Color -> Shape -> Form
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> ïŹlled (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
ïŹzzbuzz n =	

if | n % 15 == 0	

-> "ïŹzz buzz"	

| n % 3 	

== 0	

-> "ïŹzz"	

| 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

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel AraĂșjo
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

KĂŒrzlich hochgeladen (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

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 ïŹ‚ows and the propagation of change.This means that it should be possible to express static or dynamic data ïŹ‚ows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data ïŹ‚ow.
  • 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 ïŹles state changes
  • 36. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source ïŹles execution
  • 37. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source ïŹles 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 |> ïŹlled (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 |> ïŹlled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) ïŹlled : Color -> Shape -> Form
  • 89. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y radius = circle radius |> ïŹlled (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 |> ïŹlled (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 |> ïŹlled (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 >> ïŹlled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  • 96. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = circle >> ïŹlled (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) >> ïŹlled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  • 98. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> ïŹlled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) ïŹlled : Color -> Shape -> Form
  • 99. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> ïŹlled (rgb 150 170 150) >> alpha 0.5 >> move (x, y) Curried! ïŹlled : Color -> Shape -> Form
  • 100. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> ïŹlled (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 ïŹzzbuzz n = if | n % 15 == 0 -> "ïŹzz buzz" | n % 3 == 0 -> "ïŹzz" | 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
  • 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