- Install psc-package and pulp
npm i -g psc-package pulp
- Initialize the project
pulp --psc-package init
- Build the project
pulp --psc-package run
- Do your happy dance!
My first PureScript project πΊ
- PureScript by Example (Free eBook)
- Let's Build a Simon Game in PureScript
- PureScript Cheatsheet
- PureScript Slack Channel
- Creat an
index.html
at the root of your directory
touch index.html
- Add basic
html
markup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src='./output/app.js'></script>
</body>
</html>
- Run the server
pulp server
- Do your happy dance!
My first PureScript app π
- Install Pux
psc-package install pux
- Imports
import Prelude hiding (div)
import Control.Monad.Eff (Eff)
import Pux (CoreEffects, EffModel, start)
import Pux.DOM.Events (onClick)
import Pux.DOM.HTML (HTML)
import Pux.Renderer.React (renderToDOM)
import Text.Smolder.HTML (button, div, span)
import Text.Smolder.Markup (text, (#!))
- User Actions
data Event = Increment | Decrement
- State
type State = Int
- Update
foldp :: β fx. Event -> State -> EffModel State Event fx
foldp Increment n = { state: n + 1, effects: [] }
foldp Decrement n = { state: n - 1, effects: [] }
- View
view :: State -> HTML Event
view count =
div do
button #! onClick (const Increment) $ text "Increment"
span $ text (show count)
button #! onClick (const Decrement) $ text "Decrement"
- Main
main :: β fx. Eff (CoreEffects fx) Unit
main = do
app <- start
{ initialState: 0
, view
, foldp
, inputs: []
}
renderToDOM "#app" app.markup app.input
- Mount App and Add React
<body>
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<script src='./output/app.js'></script>
</body>
- Bundle and Serve
pulp server
- Do your happy dance!
My first PureScript app that does something πΊ π
- Install the aff module
psc-package install aff
- Import modules
import Control.Monad.Aff.Console (CONSOLE, log)
import Data.Maybe (Maybe(..)) -- Part of Prelude
- Define App Effects
type AppEffects = ( console:: CONSOLE )
- Log state to console
foldp :: β fx. Event -> State -> EffModel State Event AppEffects -- π
foldp Increment n = { state: n + 1, effects: [
do
log $ "Current State: " <> (show $ n + 1)
pure Nothing
]}
foldp Decrement n = { state: n - 1, effects: [
do
log $ "Current State: " <> (show $ n - 1)
pure Nothing
]}
- Update Main
main :: β fx. Eff (CoreEffects AppEffects) Unit -- π
main = do
app <- start
{ initialState: 0
, view
, foldp
, inputs: []
}
renderToDOM "#app" app.markup app.input
- Run server
pulp server
- Do your happy dance!
My first PureScript side-effect πΊ
- Install necessary modules
psc-package install argonaut-codecs affjax
- Import modules
import Control.Monad.Aff (attempt)
import Data.Argonaut.Decode (decodeJson, (.?))
import Data.Argonaut.Decode.Class (class DecodeJson)
import Data.Either (Either(Left, Right), either)
import Data.Newtype (class Newtype, un)
import Network.HTTP.Affjax (AJAX, get)
import Text.Smolder.HTML (button, div, img)
import Text.Smolder.HTML.Attributes (src)
import Text.Smolder.Markup (text, (#!), (!))
- Define effects
type AppEffects = ( console:: CONSOLE, ajax:: AJAX )
- Define user actions
data Event = RequestGiphy | ReceiveGiphy (Either String Url)
- Define a newtype (for decoding)
newtype Url = Url String
derive instance newtypeUrl :: Newtype Url _
unwrap :: Url -> String
unwrap = un Url
- Define the state
type State = Url
- Decoder
instance decodeJsonUrl :: DecodeJson Url where
decodeJson json = do
obj <- decodeJson json
info <- obj .? "data"
imgUrl <- info .? "image_original_url"
pure $ Url imgUrl
- Update
foldp :: β fx. Event -> State -> EffModel State Event AppEffects
foldp RequestGiphy state = { state: state, effects: [
do
result <- attempt $ get "https://api.giphy.com/v1/gifs/random?api_key=670526ba3bda46629f097f67890105ed&tag=&rating=G"
let decode res = decodeJson res.response :: Either String Url
let url = either (Left <<< show) decode result
pure $ Just $ ReceiveGiphy url
]}
foldp (ReceiveGiphy (Left _)) state = { state: state, effects: [ log "Error" *> pure Nothing ] }
foldp (ReceiveGiphy (Right url)) state = { state: url, effects: [ log "ReceivedGiphy" *> pure Nothing ]}
- View
view url =
div do
button #! onClick (const RequestGiphy) $ text "Get Random Giphy"
img ! src (unwrap url)
- Main
main :: β fx. Eff (CoreEffects AppEffects) Unit
main = do
app <- start
{ initialState: Url "" -- π
, view
, foldp
, inputs: []
}
renderToDOM "#app" app.markup app.input
- Run server
pulp server
- Do your happy dance!
My first PureScript HTTP request πΊ π
- Update Imports
import Pux.DOM.Events (onClick, onChange, DOMEvent, targetValue)
import Text.Smolder.HTML (button, div, img, input)
import Text.Smolder.HTML.Attributes (src, type', value)
- Update state
type State =
{ url :: Url
, input :: String
}
- Update
foldp :: β fx. Event -> State -> EffModel State Event AppEffects
foldp RequestGiphy state = { state: state, effects: [
do
result <- attempt $ get $ "https://api.giphy.com/v1/gifs/random?api_key=670526ba3bda46629f097f67890105ed&tag=" <> state.input <> "&rating=G"
let decode res = decodeJson res.response :: Either String Url
let url = either (Left <<< show) decode result
pure $ Just $ ReceiveGiphy url
]}
foldp (ReceiveGiphy (Left _)) state = { state: state, effects: [ log "Error" *> pure Nothing ] }
foldp (ReceiveGiphy (Right url)) state = { state: state { url = url }, effects: [ log "ReceivedGiphy" *> pure Nothing ]}
foldp (UserInput ev) state = { state: state { input = targetValue ev }, effects: [] }
- View
view state =
div do
input ! type' "text" #! onChange UserInput ! value state.input
button #! onClick (const RequestGiphy) $ text "Get Random Giphy"
img ! src (unwrap state.url)
- Main
main :: β fx. Eff (CoreEffects AppEffects) Unit
main = do
app <- start
{ initialState: { input: "", url: Url "" } -- π
, view
, foldp
, inputs: []
}
renderToDOM "#app" app.markup app.input
- Run server
pulp server
- Do your happy dance!
My first PureScript Giphy App π