Slide 1

Slide 1 text

PureScript Meetup #12 Pattern Matching & Algebraic Data Types CYBAI _cybai 1

Slide 2

Slide 2 text

Agenda • Pattern Matching • Guards • Case Expression • Named Patterns • Nested Patterns • Wildcard pattern • Totality 2

Slide 3

Slide 3 text

Agenda (Cont.) • Introduction to Algebraic Data Types • Sum Type • Product Type • `type` • `newtype` 3

Slide 4

Slide 4 text

Pattern Matching 4

Slide 5

Slide 5 text

What is pattern matching? 5

Slide 6

Slide 6 text

Pattern Matching gcd :: Int -> Int -> Int gcd n 0 = n gcd 0 m = m gcd n m = if n > m then gcd (n - m) m else gcd n (m - n) 6

Slide 7

Slide 7 text

Pattern Matching gcd :: Int -> Int -> Int gcd n 0 = n gcd 0 m = m gcd n m = if n > m then gcd (n - m) m else gcd n (m - n) 7 Each line is called an alternative or a case. The expressions on the left of the equals sign are called patterns

Slide 8

Slide 8 text

Pattern Matching (Cont.) 8 gcd :: Int -> Int -> Int gcd n 0 = n gcd 0 n = n gcd n m | n > m = gcd (n - m) m | otherwise = gcd n (m - n) Guards `otherwise` is an alias for `true` from `Prelude`. Ref: Pursuit of `otherwise`

Slide 9

Slide 9 text

Pattern Matching (Cont.) 9 Case Expression describeArray :: Array Int -> String describeArray xs = "This array is " <> case xs of [] -> "empty." [x] -> "a singleton array." xs -> "a longer array."

Slide 10

Slide 10 text

Pattern Matching (Cont.) 10 Named Patterns sortPair :: Array Int -> Array Int sortPair arr@[x, y] | x <= y = arr | otherwise = [y, x] sortPair arr = arr

Slide 11

Slide 11 text

Pattern Matching (Cont.) 11 Record Pattern showPerson :: { first :: String, last :: String } -> String showPerson { first: x, last: y } = y <> ", " <> x

Slide 12

Slide 12 text

Pattern Matching (Cont.) 12 type Address = { street :: String, city :: String } type Person = { name :: String, address :: Address } livesInLA :: Person -> Boolean livesInLA { address: { city: "Los Angeles" } } = true livesInLA _ = false Record Pattern w/ Nested Pattern

Slide 13

Slide 13 text

Pattern Matching (Cont.) 13 Wildcard pattern fromString :: String -> Boolean fromString "true" = true fromString _ = false

Slide 14

Slide 14 text

Pattern Matching (Cont.) 14 isEmpty :: forall a. Array a -> Boolean isEmpty [] = true isEmpty _ = false Wildcard pattern takeFive :: Array Int -> Int takeFive [0, 1, a, b, _] = a * b takeFive _ = 0

Slide 15

Slide 15 text

Pattern Matching (Cont.) • Functions which return a value for any combination of inputs are called total functions. • Functions which do not are called partial. 15 Totality Ref: PureScript By Example - CH5 - Pattern Match Failures and Partial Functions

Slide 16

Slide 16 text

Pattern Matching (Cont.) 16 Totality not :: Boolean -> Boolean not true = false Compiler will detect exhaustive which means that this function doesn’t match all the cases of `Boolean`; also, it means this is a partial function.

Slide 17

Slide 17 text

Pattern Matching (Cont.) 17 Totality import Partial.Unsafe (unsafePartial) not :: Boolean -> Boolean not = unsafePartial \true -> false If we still need to make this function as a partial function, then we need to use the `unsafePartial` function to let compiler know this is a partial function.

Slide 18

Slide 18 text

Pattern Matching (Cont.) 18 showPerson :: forall r. { first :: String, last :: String | r } -> String showPerson { first: x, last: y } = y <> ", " <> x Row Polymorphism

Slide 19

Slide 19 text

Pattern Matching (Cont.) 19 After looking these syntax, maybe some people will think: Isn’t it just like a `switch-case`?

Slide 20

Slide 20 text

Pattern Matching (Cont.) 20 After looking these syntax, maybe some people will think: Isn’t it just like a `switch-case`? No, they’re different.

Slide 21

Slide 21 text

Pattern Matching (Cont.) 21 After looking these syntax, maybe some people will think: Isn’t it just like a `switch-case`? No, they’re different. But, why? What’s the difference?

Slide 22

Slide 22 text

Pattern Matching (Cont.) 22 Let’s take a look for an example first. In JS function leftPad(str, padding) { switch (typeof padding) { case "number": return Array(padding + 1).join(" ") + str; case "string": return padding + str; default: throw new Error( `Unexpected type with '${padding}'.` ); } }

Slide 23

Slide 23 text

Pattern Matching (Cont.) 23 Let’s take a look for an example first. In PureScript data Padding = PaddingStr String | PaddingNum Int repeat :: String -> Int -> String repeat str 0 = str repeat str n = str <> (repeat str (n - 1)) leftPad :: String -> Padding -> String leftPad s (PaddingStr a) = a <> s leftPad s (PaddingNum a) = repeat " " a <> s

Slide 24

Slide 24 text

Pattern Matching (Cont.) 24 With Algebraic Data Types, the Type System of PureScript will help us to check the type w/ your data types; however, in JS, you need to check each type of value by yourself with `if` or `switch`.

Slide 25

Slide 25 text

Pattern Matching (Cont.) 25 So, yeah, the benefit of Pattern Matching is from Algebraic Data Types. Let’s dig into the world of ADTs.

Slide 26

Slide 26 text

Introduction to Algebraic Data Types 26

Slide 27

Slide 27 text

– Orah Kittrell “A type can be thought of as an enumeration of constructors that have zero or more arguments.” 27

Slide 28

Slide 28 text

Algebraic Data Types 28 Before talking about what Algebraic Data Type exactly is, let’s talk about how datatypes construct.

Slide 29

Slide 29 text

Algebraic Data Types 29 Constructors

Slide 30

Slide 30 text

Algebraic Data Types 30 data Bool = False | True

Slide 31

Slide 31 text

Algebraic Data Types 31 data Bool = False | True Declare a data type

Slide 32

Slide 32 text

Algebraic Data Types 32 data Bool = False | True Declare a data type Type Constructor without Argument

Slide 33

Slide 33 text

Algebraic Data Types 33 data Bool = False | True Declare a data type Type Constructor without Argument Data Constructors a.k.a Value Constructors In this case, it takes no arguments so we can also call it nullary constructor.

Slide 34

Slide 34 text

Algebraic Data Types 34 data Bool = False | True Declare a data type Type Constructor without Argument Data Constructors a.k.a Value Constructors In this case, it takes no arguments so we can also call it nullary constructor. This `pipe` denotes to Sum Type which we’ll mention in the later slides.

Slide 35

Slide 35 text

Algebraic Data Types 35 • Type Constructor • Data Constructor We can know there’re two kinds of constructors from previous slides: Let’s understand how they’re different.

Slide 36

Slide 36 text

Algebraic Data Types • Used at type level, in type signature, typeclass declarations and instances. (Type Class and Instance will not be covered in this slides.) • Types are static and solve at compile time. 36 Type constructors

Slide 37

Slide 37 text

Algebraic Data Types • Construct values at term level. • Can interact with the values at runtime. • Only exist in value, term, or runtime space. • value, term, and runtime space are not different but just describe the types for different spaces. 37 Data constructors Term level is where your values live and is the code that executes when your program is running.

Slide 38

Slide 38 text

Algebraic Data Types 38 Although the term constructor is often used to describe all type constructors and data constructors, we can make a distinction between constants and constructors. Ref: haskellbook - CH11

Slide 39

Slide 39 text

Algebraic Data Types 39 Constants data Bool = False | True We can see `Bool` as an example of type constants. It takes no arguments and is nullary. Also, its data constructors are also constants which also take no arguments.

Slide 40

Slide 40 text

Algebraic Data Types 40 Constructors Type constructor takes one argument. data List a = Nil | Cons a (List a) Phantom data constructor which means its type constructor has argument(s) but it doesn’t use the argument(s) like a phantom. Data constructor awaiting two values to be applied to. Besides, the values must be same type as `a` in type constructor.

Slide 41

Slide 41 text

Algebraic Data Types 41 data Bool = True | False toString :: Bool -> String toString True = "true" toString False = "false" Example

Slide 42

Slide 42 text

Algebraic Data Types 42 Algebraic

Slide 43

Slide 43 text

Algebraic Data Types 43 Arity Arity means how many arguments a function or a constructor take.

Slide 44

Slide 44 text

Algebraic Data Types 44 Arity Arity means how many arguments a function or a constructor take. nullary is combined from `null` and `-ary`. `-ary` means “of”

Slide 45

Slide 45 text

Algebraic Data Types • nullary data constructor: constructor takes no arguments • unary data constructor: constructor takes one argument • data constructor takes more than one arguments; we’ll call them products 45 Arity

Slide 46

Slide 46 text

Algebraic Data Types 46 Arity -- | nullary data Unit = Unit -- | unary data Currency = Currency Int -- | product of two points data Line = Line Point Point We’ll talk about product type in the later slides.

Slide 47

Slide 47 text

Algebraic Data Types 47 Why we call it algebraic data type?

Slide 48

Slide 48 text

Algebraic Data Types 48 Why we call it algebraic data type? Because we can understand how argument structures construct via two basic operations: sum and product.

Slide 49

Slide 49 text

Algebraic Data Types 49 Why we call it algebraic data type? Because we can understand how argument structures construct via two basic operations: sum and product. So, we can calculate how many possible implementation via type signature.

Slide 50

Slide 50 text

Algebraic Data Types 50 Sum Type

Slide 51

Slide 51 text

Algebraic Data Types 51 Sum Type The pipe operator, `|`, means “or”.

Slide 52

Slide 52 text

Algebraic Data Types 52 Sum Type The pipe operator, `|`, means “or”. This is the `sum` in algebraic data types.

Slide 53

Slide 53 text

Algebraic Data Types 53 Sum Type The pipe operator, `|`, means “or”. This is the `sum` in algebraic data types. data Bool = False | True

Slide 54

Slide 54 text

Algebraic Data Types 54 Sum Type The pipe operator, `|`, means “or”. This is the `sum` in algebraic data types. data Bool = False | True We know nullary data constructor represents only one possible. Thus, it also means 1.

Slide 55

Slide 55 text

Algebraic Data Types 55 Sum Type The pipe operator, `|`, means “or”. This is the `sum` in algebraic data types. data Bool = False | True We know nullary data constructor represents only one possible. Thus, it also means 1. We can count its cardinality to find Bool is like a set with 2 elements.

Slide 56

Slide 56 text

Algebraic Data Types 56 Sum Type: Exercise data Browser = Chrome | Firefox | Safari | Opera | Edge

Slide 57

Slide 57 text

Algebraic Data Types 57 Sum Type: Exercise data Browser = Chrome | Firefox | Safari | Opera | Edge Ans: The cardinality of `Browser` type constructor is 5.

Slide 58

Slide 58 text

Algebraic Data Types 58 Product Type

Slide 59

Slide 59 text

Algebraic Data Types 59 Product Type A product type’s cardinality is the product of the cardinalities of its data constructors.

Slide 60

Slide 60 text

Algebraic Data Types 60 Product Type A product type’s cardinality is the product of the cardinalities of its data constructors. If Sum Type represents “or”, then Product Type represents “and”.

Slide 61

Slide 61 text

Algebraic Data Types 61 Product Type A product type’s cardinality is the product of the cardinalities of its data constructors. If Sum Type represents “or”, then Product Type represents “and”. Any data constructor with more than one argument is a product.

Slide 62

Slide 62 text

Algebraic Data Types 62 Product Type A product type’s cardinality is the product of the cardinalities of its data constructors. If Sum Type represents “or”, then Product Type represents “and”. Any data constructor with more than one argument is a product. Let’s try to define one!

Slide 63

Slide 63 text

Algebraic Data Types 63 Product Type data BrowserVendor = Vendor Browser Bool

Slide 64

Slide 64 text

Algebraic Data Types 64 Product Type data BrowserVendor = Vendor Browser Bool We already knew that cardinality of Browser is 5 and cardinality of Bool is 2.

Slide 65

Slide 65 text

Algebraic Data Types 65 Product Type data BrowserVendor = Vendor Browser Bool We already knew that cardinality of Browser is 5 and cardinality of Bool is 2. [ Chrome True, Chrome False, Firefox True, Firefox False, Safari True, Safari False, Opera True, Opera False, Edge True, Edge False, ]

Slide 66

Slide 66 text

Algebraic Data Types 66 Product Type data BrowserVendor = Vendor Browser Bool We already knew that cardinality of Browser is 5 and cardinality of Bool is 2. [ Chrome True, Chrome False, Firefox True, Firefox False, Safari True, Safari False, Opera True, Opera False, Edge True, Edge False, ] If we try to enumerate this data type, then we can get the cardinality with 10 which is equal to 2 * 5.

Slide 67

Slide 67 text

Algebraic Data Types • Type synonym a.k.a Type alias • Cannot define typeclass instances • Ex. 67 type type Name = String

Slide 68

Slide 68 text

Algebraic Data Types • Define a type that can only have a unary data constructor • Cannot be a product type, sum type, or contain nullary constructors • Can define typeclass instances • No runtime overhead due to reusing the type it contains • Ex. 68 newtype newtype String = Array Char

Slide 69

Slide 69 text

Pattern Matching in JS 69 tc39/proposal-pattern-matching

Slide 70

Slide 70 text

Q & A 70

Slide 71

Slide 71 text

Thank you! 71