Slide 1

Slide 1 text

PureScript Meetup #10 PureScript By Example: CH1 - CH4 CYBAI _cybai 1

Slide 2

Slide 2 text

Agenda • What is PureScript? • Environment Setup • Syntax • Literals • Records • Function • Types • Kinds • Type Signature 2

Slide 3

Slide 3 text

Agenda (Cont.) • Syntax • Curried Function, where clause • Infix function • Function Composition (<<<, >>>) • Array • map, range, filter, concat, concatMap • do notation • guard • foldl, foldr • Tail Recursion 3

Slide 4

Slide 4 text

What is PureScript? • A static typed language • A pure functional language • Compiles to JavaScript • Inspired by Haskell 4

Slide 5

Slide 5 text

Why PureScript? Ref: Why You Should Use PureScript 5

Slide 6

Slide 6 text

Why Pure Functional Language? 6

Slide 7

Slide 7 text

Why not JS? Drawbacks in JavaScript • Unrestricted • Untyped • Not easy to form an abstraction 7

Slide 8

Slide 8 text

Environment Setup 8

Slide 9

Slide 9 text

Installation • npm i -g purescript pulp bower1 • pulp init • pulp build • pulp run • pulp repl 1: Why the PureScript community uses Bower 9

Slide 10

Slide 10 text

IDE Plugins 10

Slide 11

Slide 11 text

Useful websites • Official documents: • https://pursuit.purescript.org/ • Playground: • http://try.purescript.org/ 11

Slide 12

Slide 12 text

Syntax 12

Slide 13

Slide 13 text

Literals a = 0.0 :: Number b = 0 :: Int c = "purescript" :: String d = 'a' :: Char e = true :: Boolean f = [0] :: Array Int 13

Slide 14

Slide 14 text

Records > meetup = { category: "PureScript", place: "Taiwan" } > :type meetup { category :: String , place :: String } 14

Slide 15

Slide 15 text

Function > meetupPlace m = m.category <> " meetup @" <> m.place > m = { category: "PureScript", place: "Taiwan" } > meetupPlace m "PureScript meetup @Taiwan" 15

Slide 16

Slide 16 text

Types type Meetup = { category :: String , place :: String } 16

Slide 17

Slide 17 text

Kinds > :kind Number Type > import Data.List > :kind List Type -> Type > :kind List String Type Type Constructor 17

Slide 18

Slide 18 text

Type Signature Function Name Function Parameter Types add :: Number -> Number -> Number add x y = x + y Return Type 18

Slide 19

Slide 19 text

Curried Function addMeetup :: Meetup -> Meetups -> Meetups addMeetup m a = Cons m a > :type addMeetup meetup List { category :: String , place :: String } -> List { category :: String , place :: String } 19

Slide 20

Slide 20 text

Curried Function (Cont.) addMeetup :: Meetup -> Meetups -> Meetups addMeetup = Cons 20

Slide 21

Slide 21 text

where clause findMeetup :: String -> String -> Meetups -> Maybe Meetup findMeetup category place meetups = head $ filter filterMeetup meetups where filterMeetup :: Meetup -> Boolean filterMeetup m = m.category == category && m.place == place 21

Slide 22

Slide 22 text

Infix Function apply :: forall a b. (a -> b) -> a -> b apply f x = f x infixr 0 apply as $ 22

Slide 23

Slide 23 text

Infix Function (Cont.) head $ filter filterMeetup meetups head (filter filterMeetup meetups) 23

Slide 24

Slide 24 text

Function Composition • <<< : backwards composition • >>> : forwards composition 24

Slide 25

Slide 25 text

Function Composition (Cont.) findMeetup :: String -> String -> Meetups -> Maybe Meetup findMeetup category place = head <<< filter filterMeetup where ... findMeetup :: String -> String -> Meetups -> Maybe Meetup findMeetup category place = filter filterMeetup >>> head where ... 25

Slide 26

Slide 26 text

Recursion, Maps And Folds 26

Slide 27

Slide 27 text

Recursion: fib fib :: Int -> Int fib 0 = 1 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2) 27

Slide 28

Slide 28 text

Recursion: array import Prelude import Data.Array (null) import Data.Array.Partial (tail) import Partial.Unsafe (unsafePartial) length :: forall a. Array a -> Int length arr = if null arr then 0 else 1 + length (unsafePartial tail arr) 28

Slide 29

Slide 29 text

map map (\n -> n + 1) [1, 2, 3, 4, 5] (\n -> n + 1) `map` [1, 2, 3, 4, 5] (\n -> n + 1) <$> [1, 2, 3, 4, 5] 29

Slide 30

Slide 30 text

map (Cont.) > :type map forall a b f. Functor f => (a -> b) -> f a -> f b forall a b. (a -> b) -> Array a -> Array b > show <$> [1, 2, 3, 4, 5] ["1","2","3","4","5"] 30

Slide 31

Slide 31 text

range infix 8 range as .. > 1 .. 5 [1, 2, 3, 4, 5] > show <$> (1 .. 5) ["1","2","3","4","5"] 31

Slide 32

Slide 32 text

filter > filter (\n -> n `mod` 2 == 0) (1 .. 10) [2,4,6,8,10] 32

Slide 33

Slide 33 text

concat > :type concat forall a. Array (Array a) -> Array a > concat [[1, 2, 3], [4, 5], [6]] [1, 2, 3, 4, 5, 6] 33

Slide 34

Slide 34 text

concatMap > :type concatMap forall a b. (a -> Array b) -> Array a -> Array b > concatMap (\n -> [n, n * n]) (1 .. 5) [1,1,2,4,3,9,4,16,5,25] 34

Slide 35

Slide 35 text

Let’s write a factor function. 35

Slide 36

Slide 36 text

factor (Cont.) > import Data.Array > pairs n = concatMap (\i -> 1 .. n) (1 .. n) > pairs 3 [1,2,3,1,2,3,1,2,3] 36

Slide 37

Slide 37 text

factor (Cont.) > :paste … pairs' n = … concatMap (\i -> … map (\j -> [i, j]) (1 .. n) … ) (1 .. n) …^D > pairs' 3 [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]] 37

Slide 38

Slide 38 text

factor (Cont.) > :paste … pairs'' n = … concatMap (\i -> … map (\j -> [i, j]) (i .. n) … ) (1 .. n) …^D > pairs'' 3 [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]] 38

Slide 39

Slide 39 text

factor (Cont.) > import Data.Foldable > factors n = filter (\pair -> product pair == n) (pairs'' n) > factors 10 [[1,10],[2,5]] 39

Slide 40

Slide 40 text

`do` notation > :paste … do … i <- 1 ..3 … pure i …^D [1,2,3] 40

Slide 41

Slide 41 text

`do` notation (Cont.) > :paste … do … i <- 1 ..3 … j <- i ..3 … pure [i,j] …^D [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]] 41

Slide 42

Slide 42 text

`do` notation (Cont.) Let’s refactor the `factor` function with `do` notation. factors :: Int -> Array (Array Int) factors n = filter (\xs -> product xs == n) $ do i <- 1 .. n j <- i .. n pure [i, j] `pure` will be introduced in later Chapter; we can just understand it easily as returning the corresponding Type. In this example, we can also write `[[i,j]]`. 42

Slide 43

Slide 43 text

`do` notation (Cont.) Let’s refactor the `factor` function with `do` notation. import Control.MonadZero (guard) factors :: Int -> Array (Array Int) factors n = do i <- 1 .. n j <- i .. n guard $ i * j == n pure [i, j] Those code below `guard` will only be executed when its result is `true` 43

Slide 44

Slide 44 text

Folds > import Data.Array (foldl, foldr) > :type foldl forall a b. (b -> a -> b) -> b -> Array a -> b > :type foldr forall a b. (a -> b -> b) -> b -> Array a -> b 44

Slide 45

Slide 45 text

Folds (Cont.) > foldl (\acc n -> acc <> show n) "" [1,2,3,4,5] "12345" > foldr (\n acc -> acc <> show n) "" [1,2,3,4,5] "54321" 45

Slide 46

Slide 46 text

Tail Recursion 46

Slide 47

Slide 47 text

Tail Recursion (Cont.) > f 0 = 0 > f n = 1 + f (n - 1) > f 10 10 > f 100000 RangeError: Maximum call stack size exceeded 47

Slide 48

Slide 48 text

Tail Recursion (Cont.) fib :: Int -> Int fib = fib' 0 1 where fib' :: Int -> Int -> Int -> Int fib' acc nx 0 = (acc + nx) fib' acc nx x = fib' (acc + nx) acc (x - 1) 48

Slide 49

Slide 49 text

Tail Recursion in JS 49 Ref: ES6 compatible table

Slide 50

Slide 50 text

Q & A 50

Slide 51

Slide 51 text

References • PureScript Tutorial 1 by Ray Shih • Getting Started with PureScript by Michael Ficarra • Why the PureScript community uses Bower • Update from Bower to Psc-Package • Why You Should Use PureScript 51

Slide 52

Slide 52 text

Thank you! 52