Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PureScript TW Meetup #13: Introduction to Type Class

Fd9f21969cd8a0cbf0b2f48a9af0cc28?s=47 cybai
February 07, 2018

PureScript TW Meetup #13: Introduction to Type Class

Fd9f21969cd8a0cbf0b2f48a9af0cc28?s=128

cybai

February 07, 2018
Tweet

Transcript

  1. PureScript Meetup #13 Introduction to Type Class CYBAI _cybai 1

  2. Agenda • Introduction to Type Class • Common Type Class:

    Show, Eq, and Ord • Type Class: Semigroup, Monoid and Foldable • Derive • Comparison to Interface • References 2
  3. Syntax 3 Name of Type Class Method of this type

    class Type Signature of the method class Eq a where eq :: a -> a -> Boolean `class` keyword to declare Type Class
  4. Introduction to Type Class 4

  5. – haskellbook, CH6 “Where a declaration of a type defines

    how that type in particular is created, a declaration of a typeclass defines how a set of types are consumed or used in computations.” 5
  6. Introduction 6 If you know other programming languages with a

    similar concept, it may help to think of typeclasses as being like interfaces to data that can work across multiple datatypes. Ref: haskellbook, CH6 “The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts).”
  7. Let’s start from Common Type Class. 7

  8. Common Type Class 8 What does this mean?

  9. Common Type Class 9 This means our datatype doesn’t have

    instance of `Show` type class; thus, we need to instantiate Show for Browser datatype.
  10. Common Type Class 10 Show Ref: Data.Show type class declaration

  11. Common Type Class 11 Show instance showBrowser :: Show Browser

    where show Chrome = "Chrome" show Firefox = "Firefox" show Servo = "Servo" `instance` keyword to declare an instance of Type Class The Type Class of this instantiation The type provided for this instantiation `where` keyword terminates the initial declaration and beginning of the instance. Implement method(s) included in the Type Class
  12. Common Type Class 12 Show After instantiated, your data type

    can be shown in REPL now.
  13. Common Type Class 13 Eq Ref: Data.Eq type class declaration

  14. Common Type Class 14 Eq When we define the type

    class method, we can only define the method with type signature. Type signature can make sure that we’ll always have same type though. However, we cannot guarantee correct logic for users. Thus, we can define laws for the type class and let user follow them.
  15. Common Type Class 15 Eq Let’s have an insane example.

  16. Common Type Class 16 Eq Let’s have an insane example.

    instance eqBrowser :: Eq Browser where eq Chrome Firefox = true eq Firefox Firefox = true eq _ _ = false Obviously, we can see Chrome is equal to Firefox but Firefox is not equal to Chrome.
  17. Common Type Class 17 Eq Thus, when we’re instantiating type

    class for our datatypes, please prove it correctly. instance eqBrowser :: Eq Browser where eq Chrome Chrome = true eq Firefox Firefox = true eq Servo Servo = true eq _ _ = false
  18. Common Type Class 18 Eq After implementing the `eq` correctly,

    now we can get correct and reasonable result from it.
  19. Common Type Class 19 Ord Ref: Data.Ord type class declaration

    What’s the `Eq a` here?
  20. Common Type Class 20 Ord class Eq a <= Ord

    a where compare :: a -> a -> Ordering Using `<=` in type class means superclass for the Type Class. It means `Eq` is a superclass of `Ord` so when you’d like to instantiate `Ord` for a datatype, you should confirm it has also instantiated `Eq`.
  21. Common Type Class 21 Ord What will happen if we

    don’t instantiate `Eq` type class for the datatype when we’d like to instantiate `Ord`?
  22. Common Type Class 22 Ord data Browser = Chrome |

    Firefox | Servo instance eqBrowser :: Eq Browser where eq Chrome Chrome = true eq Firefox Firefox = true eq Servo Servo = true eq _ _ = false instance ordBrowser :: Ord Browser where compare Servo Firefox = GT compare Servo Chrome = GT compare Firefox Chrome = GT compare a b | eq a b = EQ compare _ _ = LT Let’s use guard here to simplify for equality!
  23. Common Type Class 23 Ord Then, we can compare `Ordering`

    of the datatype.
  24. 24 After introducing the three common ones, let’s continue with

    Foldable and its related Type Classes to get more familiar with Type Class! Semigroup, Monoid and Foldable
  25. Type Class: Semigroup 25 Ref: Data.Semigroup type class declaration

  26. Type Class: Semigroup 26 Ref: Pursuit of Semigroup The law

    of Semigroup
  27. Type Class: Semigroup 27 As we saw the law in

    previous slides, it must be associative. So, if we’d like to make any type as an instance of Semigroup, remember to follow the law to instantiate it!
  28. Type Class: Monoid 28 Ref: Data.Monoid type class declaration

  29. Type Class: Monoid 29 Ref: Data.Monoid type class declaration How’s

    the law for Monoid?
  30. Type Class: Monoid 30 Ref: Data.Monoid type class declaration •

    Left identity • Right identity
  31. Type Class: Monoid 31 Ref: Data.Monoid type class declaration As

    a Monoid, we usually see it as a “Empty” value for your type.
  32. Type Class: Monoid 32 Ref: Data.Monoid type class declaration For

    Example,
  33. Type Class: Monoid 33 Ref: Data.Monoid type class declaration For

    Example, We can always have the original array no matter we do left append or right append with empty array.
  34. Type Class: Monoid 34 Ref: Data.Monoid type class declaration For

    Example, We can always have the original array no matter we do left append or right append with empty array. We can always have same string no matter we do left concat or right concat with empty string.
  35. Type Class: Foldable 35 Ref: Data.Foldable type class declaration

  36. Type Class: Foldable 36 Ref: Data.Foldable type class declaration When

    we make a type as an instance of Foldable, it means the type can be folded.
  37. Type Class: Foldable 37 Ref: Data.Foldable type class declaration

  38. Type Class: Foldable 38 Ref: Data.Foldable type class declaration Member

    Methods foldr is same as reduceRight in JavaScript. foldl is same as reduce in JavaScript.
  39. Type Class: Foldable 39 Ref: Data.Foldable type class declaration Member

    Methods How about foldMap?
  40. Type Class: Foldable 40 Ref: Data.Foldable type class declaration Member

    Methods How about foldMap?
  41. Type Class: Foldable 41 Ref: Data.Foldable type class declaration Member

    Methods How about foldMap? Looking at the type signature of foldMap. We can know the m argument must be a Monoid. So, we can handle the folding for the empty case via mempty. Let’s see an example with showing an array.
  42. Type Class: Foldable 42 Ref: Data.Foldable type class declaration foldMap

    Example: Show an array with joined text With foldr or foldl, With foldMap,
  43. Type Class: Foldable 43 Ref: Data.Foldable type class declaration foldMap

    Example: Show an array with joined text The first argument of foldMap is a function which takes a type a and return a Monoid m. And, show is a function which takes a type a and return a String which is a Monoid. foldMap implementation of Array is folding from mempty as a starting point; mempty of String is an empty String. So, we don’t need to pass the second argument like in foldl or foldr which is an empty String.
  44. Type Class: Foldable 44 Ref: Data.Foldable type class declaration

  45. Derive 45 When we use `derive`, compiler will instantiate the

    type class automatically. derive instance eqBrowser :: Eq Browser instance eqBrowser :: Eq Browser where eq Chrome Chrome = true eq Firefox Firefox = true eq Servo Servo = true eq _ _ = false Same
  46. Derive (Cont.) 46 Ref: Type Class Deriving Currently supported derivable

    Type Class in PureScript
  47. Comparison to Interface 47

  48. Comparison to Interface 48 Different Types

  49. Comparison to Interface 49 Different Types class Eq a <=

    Ord a where compare :: a -> a -> Ordering In PureScript / Haskell, via type signature, we can know that we’ll have same type, `a`, of arguments in `compare` function. Ref: How do type classes differ from interfaces?
  50. 50 Comparison to Interface Different Types public interface Ord extends

    Eq { public Ordering compare(Ord other); } public enum Ordering { LT, EQ, GT } public class OrdUtil { static <A extends Ord> bool lessThanOrEqual(A a1, A a2) { Ordering result = a1.compare(a2); return result == LT || result == EQ; } } In Java, we can `extends` Ord interface; however, it cannot make sure the type `A` are always same type. Ref: How do type classes differ from interfaces?
  51. Comparison to Interface 51 Separation of Implementation

  52. 52 Comparison to Interface Ref: How do type classes differ

    from interfaces? Separation of Implementation Let’s assume this Large is from a upstream package.
  53. 53 Comparison to Interface Ref: How do type classes differ

    from interfaces? Separation of Implementation interface SomeOtherPackage { public bool doSomeThing(int lol); } public class MyLarge implements SomeOtherPackage { public final Large large; public MyLarge(Large large) { this.large = large; } public bool doSomething(int lol) { System.out.println("wut"); } } If we’d like to create our `interface`, we’ll need to create a new Class to wrap the `Large`.
  54. 54 Comparison to Interface Ref: How do type classes differ

    from interfaces? Separation of Implementation import JokesAreFun (ToyOrd( ..)) class MyNewClass a where doSomething :: a -> Int -> IO () instance MyNewClass ToyOrd where doSomething Smol x = putStrLn "hahahaa yess" doSomething (Large x) y = putStrLn ("numbers! " ++ show (x + y)) “Type classes separate the definition of data types and the instances of a class.” So, when we need to create our own type class and instantiate it for upstream package datatype, we can just make the datatype as one of instance of our new type class.
  55. Q & A 55

  56. Thank you! 56