Slide 1

Slide 1 text

GETTING STARTED WITH PURESCRIPT Michael Ficarra

Slide 2

Slide 2 text

Literals a = 0.0 :: Number b = "a" :: String c = true :: Boolean d = [0.0] :: Array Number e = {foo: 0.0} :: { foo :: Number } f = (\a -> a) :: forall a. a -> a

Slide 3

Slide 3 text

Function Definition & Application sum :: Int -> Int -> Int sum a b = a + b successor :: Int -> Int successor = sum 1 sumSuccessors :: Int -> Int -> Int sumSuccessors a b = sum (successor a) (successor b) seven :: Int seven = sumSuccessors 2 3

Slide 4

Slide 4 text

Function Definition (cont.) identity :: forall t. t -> t identity a = a const :: forall a b. a -> b -> a const x y = x ($) :: forall a b. (a -> b) -> a -> b ($) f x = f x infixr 0 $

Slide 5

Slide 5 text

Records hank :: { name :: String, birthYear :: Int } hank = {name: "Hank", birthYear: 1985} laptop :: { name :: String, mfgDate :: Int } laptop = {name: "Hotaru", mfgDate: 2014} greet :: forall r. { name :: String | r } -> String greet namedThing = "Hello, " ++ namedThing.name hankJr :: { name :: String, birthYear :: Int } hankJr = hank { birthYear = 2010 }

Slide 6

Slide 6 text

Algebraic Data Types data Ordering = Less | Equal | Greater compare :: Number -> Number -> Ordering compare a b = if a < b then Less else if a == b then Equal else Greater

Slide 7

Slide 7 text

Algebraic Data Types (cont.) data List t = EmptyList | Cons t (List t) listA :: List Number listA = Cons 0.0 (Cons 1.0 (Cons 2.0 EmptyList)) listB :: List String listB = Cons "x" (Cons "y" EmptyList) listC :: forall a. List a listC = EmptyList

Slide 8

Slide 8 text

Type Aliases type Option = Maybe type NumberArray = Array Number type NumberList = List Number type Point = { x :: Number, y :: Number } type Pair a b = { left :: a, right :: b } type Predicate a = a -> Boolean

Slide 9

Slide 9 text

Pattern Matching data Maybe t = Nothing | Just t map :: forall a b. (a -> b) -> Maybe a -> Maybe b map f Nothing = Nothing map f (Just x) = Just (f x) map' f maybe = case maybe of Nothing -> Nothing (Just x) -> Just (f x)

Slide 10

Slide 10 text

Pattern Matching (cont.) type Point = { x :: Number, y :: Number } doubleZero :: Point -> Point doubleZero p@{ x: 0, y: y } = p { y = y * 2.0 } doubleZero p = p const :: forall a b. a -> b -> a const x _ = x

Slide 11

Slide 11 text

Program Structure module Namespace.ModuleName where import OtherNamespace.OtherModule data Type0 t = Constructor0 t | Constructor1 t t value0 = Constructor1 0 1 value1 = Constructor0 "string"

Slide 12

Slide 12 text

Program Structure (cont.) module ModuleName (value0, main, Type0(..)) where import OtherModule (value1, Type1(..)) import qualified Prelude as P data Type0 t = Constructor0 t | Constructor1 t t value0 :: Type0 Int value0 = Constructor1 0 1 main :: Eff () Unit main = P.return P.unit

Slide 13

Slide 13 text

Hello, World! module Main (main) where import Control.Monad.Eff (Eff(..)) import qualified Control.Monad.Eff.Console as Console main :: Eff (console :: Console.CONSOLE) Unit main = Console.log "Hello, World!"

Slide 14

Slide 14 text

Effects module EffExample (main) where import Control.Monad.Eff (Eff(..)) import Control.Monad.Eff.Random (random, RANDOM()) -- random :: Eff (random :: RANDOM) Number import Control.Monad.Eff.Console (log, print, CONSOLE()) -- log :: String -> Eff (console :: CONSOLE) Unit -- print :: ... -> Eff (console :: CONSOLE) Unit main :: Eff (console :: CONSOLE, random :: RANDOM) Unit main = random >>= print

Slide 15

Slide 15 text

Composing Effects main :: Eff (console :: CONSOLE, random :: Random) Unit main = do a <- random b <- random log "First random number:" print a log "Second random number:" print b

Slide 16

Slide 16 text

Type Classes class Show a where show :: a -> String instance showBoolean :: Show Boolean where show true = "true" show false = "false" instance showArray :: (Show a) => Show (Array a) where show array = "[" <> map show array <> ]"

Slide 17

Slide 17 text

JavaScript Interoperability (FFI) -- MyModule.purs foreign import parseFloat :: String -> Number foreign import pow :: Number -> Number -> Number // MyModule.js exports.parseFloat = parseFloat; exports.pow = function pow(base) { return function(exponent) { return Math.pow(base, exponent); }; };

Slide 18

Slide 18 text

JavaScript Interoperability (cont.) foreign import data TimeoutID :: * foreign import data TIMER :: ! foreign import setTimeout :: forall e. Eff e Unit -> Number -> Eff (timer :: TIMER) TimeoutID foreign import clearTimeout :: TimeoutID -> Eff (timer :: TIMER) Unit

Slide 19

Slide 19 text

Installation Precompiled Binaries https://github.com/purescript/purescript/releases/latest Cabal $ cabal update $ cabal install purescript Brew $ brew update $ brew install purescript npm $ npm install -g purescript

Slide 20

Slide 20 text

Starting a Project Pulp $ npm install -g pulp $ pulp init Yeoman with Gulp $ npm install -g yo generator-purescript bower $ yo purescript Do-It-Yourself $ mkdir -p src/Namespace/Namespace $ touch !$/ModuleName.purs

Slide 21

Slide 21 text

Building Pulp $ pulp build Gulp $ gulp Do-It-Yourself $ psc 'src/**/*.purs' --ffi 'src/**/*.js' \ 'bower_components/purescript-*/src/**/*.purs' \ --ffi 'bower_components/purescript-*/src/**/*.js' $ psc-bundle --module ModuleName --main ModuleName.Main \ 'output/**/*.js' > dist/ModuleName.js

Slide 22

Slide 22 text

Managing Dependencies Install Bower $ npm install -g bower $ bower init Install Dependencies $ bower install --save purescript-monoid $ bower install --save-dev purescript-quickcheck Publish $ git tag -a v1.0.0 -m 'Version 1.0.0' $ git push --tags $ bower register

Slide 23

Slide 23 text

Testing module Test.Main (main) where import Test.QuickCheck (quickCheck) import Data.Array (sort, length) sortIsIdempotent :: Array Number -> Boolean sortIsIdempotent a = sort (sort a) == sort a sortPreservesLength :: Array Number -> Boolean sortPreservesLength a = length (sort a) == length a main = do quickCheck sortIsIdempotent quickCheck sortPreservesLength

Slide 24

Slide 24 text

Testing (cont.) $ bower install --save-dev purescript-quickcheck ... $ pulp test * Building project in /path/to/purescript-arrays * Build successful. Running tests... 100/100 test(s) passed. 100/100 test(s) passed. * Tests OK.

Slide 25

Slide 25 text

Unit Tests main = runNode [consoleReporter] do describe "Data.Array" do describe "range" do it "creates a range" do range 3 5 `shouldEqual` [3, 4, 5] range 1 100 `shouldContain` 50 describe "length" do it "calculates the length" do length [] `shouldEqual` 0 length [0] `shouldEqual` 1 length [[0, 0], [0, 0]] `shouldEqual` 2 describe "cons" do pending "cons tests"

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

Big Changes in 0.7.x ● (32-bit) Int type and integer literals ● character literals ● no more Prelude auto-import ● no more [a] notation for Array types ● no more (a:as) cons patterns ● no more inline FFI ● new typeclasses: Ring, Lattice, Bounded, Poset, ... ● effects in PSCi ● fix suggestions in error messages

Slide 34

Slide 34 text

No content