SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
PureScript & Pux
Aplicações front-end com segurança de tipos
Olá, meu nome é
Arthur Xavier
Interfaces de usuário
Gerenciamento de estado é difícil
Interfaces imperativas são pouco previsíveis
Mutabilidade torna difícil pensar sobre uma aplicação
Interfaces declarativas
Programação funcional é naturalmente declarativa
Provê um bom arcabouço para a criação de UIs declarativas
Natureza matemática
ui : ℕ → HTML
ui(x) = <span> x </span>
React
React
Biblioteca
Interfaces declarativas
Virtual DOM
Elm
Elm
Aplicações front-end (browser)
Estaticamente tipada
Elm Architecture
Single source-of-truth
PURESCRIPT
PURESCRIPT
Propósito geral
Estaticamente tipada
Funcional pura
Compila para JavaScript
Pureza funcional
function average(nums) {
let total = 0
nums.forEach((num) => {
total += num
})
return total / nums.length
}
function averageWithSideEffects(nums) {
let total = 0
nums.forEach((num) => {
fireZeMissiles()
total += num
})
return total / nums.length
}
averageWithSideEffects :: Array Int -> Eff (missiles :: MISSILES) Int
averageWithSideEffects nums = do
fireZeMissiles
pure $ (sum nums) / (length nums)
Efeitos colaterais
Eff (Effects) ResultType
Aff (Effects) ResultType
window :: forall eff. Eff (dom :: DOM | eff) Window
alert :: forall eff. String -> Window -> Eff (dom :: DOM | eff) Unit
randomInt :: Int -> Int -> Eff (random :: RANDOM) Int
setClassName :: String -> Element -> Eff (dom :: DOM) Unit
getUserById :: UserId -> Aff (ajax :: AJAX) User
Exemplos
version :: String
version = "v1.0"
add :: Number -> Number -> Number
add a b = a + b
increment :: _
increment = add 1
incrementArray :: Array Number -> Number
incrementArray array = map (add 1) array
sum :: Array Number -> Number
sum = foldl (+) 0.0
increment :: Number -> Number
incrementArray array = map increment array
incrementArray array = map (_ + 1) array
sum array = foldl (+) 0.0 array
type User =
{ name :: String
, email :: String
}
data Color = Red | Green | Blue | Black | White
data Point = Point Number Number
addPoints :: Point -> Point -> Point
addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2)
nextColor :: Color -> Color
nextColor Red = Green
nextColor Green = Blue
nextColor Blue = Red
nextColor Black = White
data Color = Red | Green | Blue | Black | White
data Point = Point Number Number
addPoints :: Point -> Point -> Point
addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2)
nextColor :: Color -> Color
nextColor Red = Green
nextColor Green = Blue
nextColor Blue = Red
nextColor Black = White
nextColor White = Black
A case expression could not be determined to cover all inputs.
The following additional cases are required to cover all inputs...
data Maybe a = Nothing | Just a
data Point a = Point a a
data Tuple a b = Tuple a b
data Either a b = Left a | Right b
-- data Result a b = Error a | Done b
fatorial :: Int -> Number
fatorial 0 = 1
fatorial 1 = 1
fatorial x = x * (fatorial (x - 1))
sum :: List Number -> Number
sum Nil = 0
sum (Cons x xs) = x + (sum xs)
getUser :: Email -> Maybe User
printUserName :: Email -> Eff (console :: CONSOLE) _
printUserName person =
case getUser email of
Nothing ->
log "Não foi encontrado usuário com este email"
Just user ->
log $ "Email: " <> email <> ", nome: " <> user.name
type User =
{ name :: String
, email :: String
}
newtype Email = Email String
type User =
{ name :: String
, email :: Email
}
parseEmail :: String -> Maybe Email
parseEmail emailStr =
if test emailRegex emailStr
then Just (Email emailStr)
else Nothing
data Maybe a = Nothing | Just a
data Permissions = BlockUser | BanUser | RemovePosts
data UserType = Guest | User | Admin
type User =
{ name :: Maybe String
, email :: Maybe Email
, permissions :: Array Permission
, userType :: UserType
}
data Permissions = BlockUser | BanUser | RemovePosts
data UserType = Guest | User | Admin
type User =
{ name :: Maybe String
, email :: Maybe Email
, permissions :: Array Permission
, userType :: UserType
}
data Permissions = BlockUser | BanUser | RemovePosts
data User
= Guest
| User
{ name :: String
, email :: Email
}
| Admin
{ name :: String
, email :: Email
, permissions :: Array Permission
}
showLoginStatus :: User -> String
showLoginStatus Guest = "Login here!"
showLoginStatus (User { name }) = "Welcome back, " <> name <> "!"
showLoginStatus (Admin { name }) = "All hail, " <> name <> "!"
Pux
data Action = Increment | Decrement
type State = Int
update :: Action -> State -> State
update Increment count = count + 1
update Decrement count = count - 1
view :: State -> Html Action
view count =
div
[]
[ button [ onClick (const Increment) ] [ text "Increment" ]
, span [] [ text (show count) ]
, button [ onClick (const Decrement) ] [ text "Decrement" ]
]
Pux
HTML
const View = () => (
<div className="example">
<h1>Hello</h1>
<h4>World</h4>
</div>
)
Pux
HTML
view =
div
[ className "example" ]
[ h1 [] [ text "Hello" ]
, h4 [] [ text "World" ]
]
-- ou
view =
div
! className "example"
##
[ h1 # text "Hello"
, h4 # text "World"
]
Pux
Componentes React
-- Spectacle.purs
foreign import codePane :: Component
// Spectacle.js
var Pux = require('purescript-pux')
var Spectacle = require('spectacle')
exports.codePane = Pux.fromReact(Spectacle.CodePane)
Pux
Aplicação
main = do
app <- start
{ initialState: 0
, update
, view
, inputs: []
}
renderToDOM "#app" app.html
Exemplo
https://github.com/arthur-xavier/purescript-pux-dice
data Die = D4 | D6 | D8 | D10 | D20
instance showDie :: Show Die where
show D4 = "D4"
show D6 = "D6"
show D8 = "D8"
show D10 = "D10"
show D20 = "D20"
dieNumber :: Die -> Int
dieNumber D4 = 4
dieNumber D6 = 6
dieNumber D8 = 8
dieNumber D10 = 10
dieNumber D20 = 20
data Action
= SelectDie Die
| Roll
| Result Int
data DiceState
= DieSelected Die
| Rolled { die :: Die, result :: Int }
type State = Maybe DiceState
init :: State
init = Nothing
update :: forall eff. Action -> State -> EffModel State Action (random :: RANDOM | eff)
update action state =
case action, state of
SelectDie die, _ ->
noEffects $ Just (DieSelected die)
Roll, Just s ->
{ state
, effects: [ do
result <- liftEff $ roll s
pure $ Result result
]
}
...
...
Result result, Just (DieSelected die) ->
noEffects $ Just (Rolled { die, result })
Result result, Just (Rolled { die }) ->
noEffects $ Just (Rolled { die, result })
_, Nothing ->
noEffects state
where
roll = randomInt 1 <<< dieNumber <<< getDie
getDie (DieSelected die) = die
getDie (Rolled {die}) = die
view :: State -> Html Action
view state =
div
##
[ h1 [] [ text "D&D randomizer" ]
, renderState state
]
renderState :: State -> Html Action
renderState state =
case state of
Nothing ->
div
##
[ h2 [] [ text "Please, select a die" ]
, div
## map renderDie dice
]
Just (DieSelected die) ->
div
##
[ div
##
[ h2 [] [ text "Dice" ]
, div
## map renderDie dice
]
, h3 [] [ text $ "Die: " <> show die ]
, button [ onClick (const Roll) ] [ text "Roll" ]
]
...
...
Just (Rolled {die, result}) ->
div
##
[ div
##
[ h2 [] [ text "Dice" ]
, div
## map renderDie dice
]
, h3 [] [ text $ "Die: " <> show die ]
, h3 [] [ text (show result) ]
, button [ onClick (const Roll) ] [ text "Roll" ]
]
where
dice = [D4, D6, D8, D10, D20]
renderDie die =
button [ onClick (const $ SelectDie die) ] [ text (show die) ]
https://arthur-xavier.github.io/purescript-pux-dice/
PURESCRIPT
O mau
Pre 1.0.0 ~ breaking changes
(mas 1.0.0 está bem próximo)
Curva de aprendizado um pouco longa
(em comparação com Elm)
PURESCRIPT
O feio
Mensagens de erro deixam a desejar
Sistema de tipos poderoso
Excelente ferramental
FFI simples e fácil
Muitos backends (JS, C++, Erlang)
Gera JavaScript legível (sem runtime)
Comunidade aberta
Se compila, funciona (95% das vezes)
PURESCRIPT
O bom
Pux
O mau
Boilerplate heavy
(assim como Elm e Redux)
Componentes não compõem bem
Pux
O feio
Sintaxe de View é feia
(assim como Elm)
Pux
O bom
FRP
Fácil
Hot reloading
Time travel debugging
Recursos
PURESCRIPT
PureScript by Example
Phil Freeman
Haskell Programming (haskellbook.com)
Julie Moronuki & Christopher Allen
fpchat.com #purescript
Slack
Building a Graphical IDE in Elm/PureScript
Claudia Doppioslash
Pux
www.alexmingoia.com/purescript-pux
pux-starter-app
github.com/alexmingoia/pux-starter-app
alexmingoia/purescript-pux
Gitter
PureScript & Pux
Michael Trotter
Pux
Obrigado
goo.gl/8vV5bP
@arthurxavierx @arthur-xavier

Weitere ähnliche Inhalte

Was ist angesagt?

Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Yury Chemerkin
 
Json and SQL DB serialization Introduction with Play! and Slick
Json and SQL DB serialization Introduction with Play! and SlickJson and SQL DB serialization Introduction with Play! and Slick
Json and SQL DB serialization Introduction with Play! and Slick
Stephen Kemmerling
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
OdessaJS Conf
 
Python tutorialfeb152012
Python tutorialfeb152012Python tutorialfeb152012
Python tutorialfeb152012
Shani729
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
Rajiv Risi
 

Was ist angesagt? (19)

The Ring programming language version 1.5.2 book - Part 43 of 181
The Ring programming language version 1.5.2 book - Part 43 of 181The Ring programming language version 1.5.2 book - Part 43 of 181
The Ring programming language version 1.5.2 book - Part 43 of 181
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODN
 
Json and SQL DB serialization Introduction with Play! and Slick
Json and SQL DB serialization Introduction with Play! and SlickJson and SQL DB serialization Introduction with Play! and Slick
Json and SQL DB serialization Introduction with Play! and Slick
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
 
The Ring programming language version 1.5.3 book - Part 42 of 184
The Ring programming language version 1.5.3 book - Part 42 of 184The Ring programming language version 1.5.3 book - Part 42 of 184
The Ring programming language version 1.5.3 book - Part 42 of 184
 
The Ring programming language version 1.10 book - Part 52 of 212
The Ring programming language version 1.10 book - Part 52 of 212The Ring programming language version 1.10 book - Part 52 of 212
The Ring programming language version 1.10 book - Part 52 of 212
 
Python tutorialfeb152012
Python tutorialfeb152012Python tutorialfeb152012
Python tutorialfeb152012
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
The Ring programming language version 1.5.1 book - Part 41 of 180
The Ring programming language version 1.5.1 book - Part 41 of 180The Ring programming language version 1.5.1 book - Part 41 of 180
The Ring programming language version 1.5.1 book - Part 41 of 180
 
The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181
 
The Ring programming language version 1.9 book - Part 52 of 210
The Ring programming language version 1.9 book - Part 52 of 210The Ring programming language version 1.9 book - Part 52 of 210
The Ring programming language version 1.9 book - Part 52 of 210
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
The Ring programming language version 1.7 book - Part 46 of 196
The Ring programming language version 1.7 book - Part 46 of 196The Ring programming language version 1.7 book - Part 46 of 196
The Ring programming language version 1.7 book - Part 46 of 196
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
 
The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기
 

Ähnlich wie PureScript & Pux

JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 

Ähnlich wie PureScript & Pux (20)

Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Introduction to python programming 1
Introduction to python programming   1Introduction to python programming   1
Introduction to python programming 1
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
 
A Tour of Building Web Applications with R Shiny
A Tour of Building Web Applications with R Shiny A Tour of Building Web Applications with R Shiny
A Tour of Building Web Applications with R Shiny
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
 
The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 

Kürzlich hochgeladen

Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Kürzlich hochgeladen (20)

Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 

PureScript & Pux

  • 1. PureScript & Pux Aplicações front-end com segurança de tipos
  • 2. Olá, meu nome é Arthur Xavier
  • 3. Interfaces de usuário Gerenciamento de estado é difícil Interfaces imperativas são pouco previsíveis Mutabilidade torna difícil pensar sobre uma aplicação
  • 4. Interfaces declarativas Programação funcional é naturalmente declarativa Provê um bom arcabouço para a criação de UIs declarativas Natureza matemática ui : ℕ → HTML ui(x) = <span> x </span>
  • 7. Elm
  • 8. Elm Aplicações front-end (browser) Estaticamente tipada Elm Architecture Single source-of-truth
  • 12. function average(nums) { let total = 0 nums.forEach((num) => { total += num }) return total / nums.length }
  • 13. function averageWithSideEffects(nums) { let total = 0 nums.forEach((num) => { fireZeMissiles() total += num }) return total / nums.length }
  • 14. averageWithSideEffects :: Array Int -> Eff (missiles :: MISSILES) Int averageWithSideEffects nums = do fireZeMissiles pure $ (sum nums) / (length nums)
  • 16. Eff (Effects) ResultType Aff (Effects) ResultType
  • 17. window :: forall eff. Eff (dom :: DOM | eff) Window alert :: forall eff. String -> Window -> Eff (dom :: DOM | eff) Unit randomInt :: Int -> Int -> Eff (random :: RANDOM) Int setClassName :: String -> Element -> Eff (dom :: DOM) Unit getUserById :: UserId -> Aff (ajax :: AJAX) User
  • 19. version :: String version = "v1.0" add :: Number -> Number -> Number add a b = a + b increment :: _ increment = add 1 incrementArray :: Array Number -> Number incrementArray array = map (add 1) array sum :: Array Number -> Number sum = foldl (+) 0.0 increment :: Number -> Number incrementArray array = map increment array incrementArray array = map (_ + 1) array sum array = foldl (+) 0.0 array
  • 20. type User = { name :: String , email :: String }
  • 21. data Color = Red | Green | Blue | Black | White data Point = Point Number Number addPoints :: Point -> Point -> Point addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2) nextColor :: Color -> Color nextColor Red = Green nextColor Green = Blue nextColor Blue = Red nextColor Black = White
  • 22. data Color = Red | Green | Blue | Black | White data Point = Point Number Number addPoints :: Point -> Point -> Point addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2) nextColor :: Color -> Color nextColor Red = Green nextColor Green = Blue nextColor Blue = Red nextColor Black = White nextColor White = Black A case expression could not be determined to cover all inputs. The following additional cases are required to cover all inputs...
  • 23. data Maybe a = Nothing | Just a data Point a = Point a a data Tuple a b = Tuple a b data Either a b = Left a | Right b -- data Result a b = Error a | Done b
  • 24. fatorial :: Int -> Number fatorial 0 = 1 fatorial 1 = 1 fatorial x = x * (fatorial (x - 1)) sum :: List Number -> Number sum Nil = 0 sum (Cons x xs) = x + (sum xs) getUser :: Email -> Maybe User printUserName :: Email -> Eff (console :: CONSOLE) _ printUserName person = case getUser email of Nothing -> log "Não foi encontrado usuário com este email" Just user -> log $ "Email: " <> email <> ", nome: " <> user.name
  • 25. type User = { name :: String , email :: String } newtype Email = Email String type User = { name :: String , email :: Email } parseEmail :: String -> Maybe Email parseEmail emailStr = if test emailRegex emailStr then Just (Email emailStr) else Nothing data Maybe a = Nothing | Just a
  • 26. data Permissions = BlockUser | BanUser | RemovePosts data UserType = Guest | User | Admin type User = { name :: Maybe String , email :: Maybe Email , permissions :: Array Permission , userType :: UserType }
  • 27. data Permissions = BlockUser | BanUser | RemovePosts data UserType = Guest | User | Admin type User = { name :: Maybe String , email :: Maybe Email , permissions :: Array Permission , userType :: UserType }
  • 28. data Permissions = BlockUser | BanUser | RemovePosts data User = Guest | User { name :: String , email :: Email } | Admin { name :: String , email :: Email , permissions :: Array Permission }
  • 29. showLoginStatus :: User -> String showLoginStatus Guest = "Login here!" showLoginStatus (User { name }) = "Welcome back, " <> name <> "!" showLoginStatus (Admin { name }) = "All hail, " <> name <> "!"
  • 30. Pux
  • 31. data Action = Increment | Decrement type State = Int update :: Action -> State -> State update Increment count = count + 1 update Decrement count = count - 1 view :: State -> Html Action view count = div [] [ button [ onClick (const Increment) ] [ text "Increment" ] , span [] [ text (show count) ] , button [ onClick (const Decrement) ] [ text "Decrement" ] ]
  • 32. Pux HTML const View = () => ( <div className="example"> <h1>Hello</h1> <h4>World</h4> </div> )
  • 33. Pux HTML view = div [ className "example" ] [ h1 [] [ text "Hello" ] , h4 [] [ text "World" ] ] -- ou view = div ! className "example" ## [ h1 # text "Hello" , h4 # text "World" ]
  • 34. Pux Componentes React -- Spectacle.purs foreign import codePane :: Component // Spectacle.js var Pux = require('purescript-pux') var Spectacle = require('spectacle') exports.codePane = Pux.fromReact(Spectacle.CodePane)
  • 35. Pux Aplicação main = do app <- start { initialState: 0 , update , view , inputs: [] } renderToDOM "#app" app.html
  • 37. data Die = D4 | D6 | D8 | D10 | D20 instance showDie :: Show Die where show D4 = "D4" show D6 = "D6" show D8 = "D8" show D10 = "D10" show D20 = "D20" dieNumber :: Die -> Int dieNumber D4 = 4 dieNumber D6 = 6 dieNumber D8 = 8 dieNumber D10 = 10 dieNumber D20 = 20
  • 38. data Action = SelectDie Die | Roll | Result Int data DiceState = DieSelected Die | Rolled { die :: Die, result :: Int } type State = Maybe DiceState init :: State init = Nothing
  • 39. update :: forall eff. Action -> State -> EffModel State Action (random :: RANDOM | eff) update action state = case action, state of SelectDie die, _ -> noEffects $ Just (DieSelected die) Roll, Just s -> { state , effects: [ do result <- liftEff $ roll s pure $ Result result ] } ...
  • 40. ... Result result, Just (DieSelected die) -> noEffects $ Just (Rolled { die, result }) Result result, Just (Rolled { die }) -> noEffects $ Just (Rolled { die, result }) _, Nothing -> noEffects state where roll = randomInt 1 <<< dieNumber <<< getDie getDie (DieSelected die) = die getDie (Rolled {die}) = die
  • 41. view :: State -> Html Action view state = div ## [ h1 [] [ text "D&D randomizer" ] , renderState state ]
  • 42. renderState :: State -> Html Action renderState state = case state of Nothing -> div ## [ h2 [] [ text "Please, select a die" ] , div ## map renderDie dice ] Just (DieSelected die) -> div ## [ div ## [ h2 [] [ text "Dice" ] , div ## map renderDie dice ] , h3 [] [ text $ "Die: " <> show die ] , button [ onClick (const Roll) ] [ text "Roll" ] ] ...
  • 43. ... Just (Rolled {die, result}) -> div ## [ div ## [ h2 [] [ text "Dice" ] , div ## map renderDie dice ] , h3 [] [ text $ "Die: " <> show die ] , h3 [] [ text (show result) ] , button [ onClick (const Roll) ] [ text "Roll" ] ] where dice = [D4, D6, D8, D10, D20] renderDie die = button [ onClick (const $ SelectDie die) ] [ text (show die) ]
  • 45. PURESCRIPT O mau Pre 1.0.0 ~ breaking changes (mas 1.0.0 está bem próximo) Curva de aprendizado um pouco longa (em comparação com Elm)
  • 46. PURESCRIPT O feio Mensagens de erro deixam a desejar
  • 47. Sistema de tipos poderoso Excelente ferramental FFI simples e fácil Muitos backends (JS, C++, Erlang) Gera JavaScript legível (sem runtime) Comunidade aberta Se compila, funciona (95% das vezes) PURESCRIPT O bom
  • 48. Pux O mau Boilerplate heavy (assim como Elm e Redux) Componentes não compõem bem
  • 49. Pux O feio Sintaxe de View é feia (assim como Elm)
  • 52. PURESCRIPT PureScript by Example Phil Freeman Haskell Programming (haskellbook.com) Julie Moronuki & Christopher Allen fpchat.com #purescript Slack Building a Graphical IDE in Elm/PureScript Claudia Doppioslash