SlideShare a Scribd company logo
1 of 14
Download to read offline
ABSTRACT TYPECLASSES
— HOW TO DESIGN A
FUTURE-PROOF TYPECLASS
@mod_poppo
2019-11-09
CHANGES TO TYPECLASSES
• Functor-Applicative-Monad
• Semigroup-Monoid
• MonadFail
MIGRATION IS PAINFUL
• Adding a superclass
• data Foo a = …

instance Monad Foo where …

-- No instance for Applicative Foo
• Removing a method
• instance Monad Foo where …

fail x = …

-- 'fail' is not a (visible) method of class
'Monad'
• Sometimes #ifdef s cannot be avoided 😵
ABSTRACT TYPECLASS
• A data type whose constructors are hidden is abstract
• data Foo = {- hidden -}
• A similar concept could be employed to type classes: A type class
whose methods are hidden
• class Foo a where {- hidden -}
AN EXAMPLE OF ABSTRACT TYPECLASS
• An example of abstract
typeclass is
GHC.TypeLits.KnownN
at
• Its method natSing is
hidden
• The user can use this
class via

natVal :: KnownNat
n => proxy n ->
Integer
THE MERIT OF BEING ABSTRACT
• The author of the class can freely change the definition of the
class
• e.g. KnownNat has changed its representation since GHC 8.2
(Integer → Natural)
• The user doesn't need to care if its representation changed, as
long as natVal doesn't change
MAKING ‘Monad’ CLASS ABSTRACT
• module MyMonad (MyMonad, (>>=), return, fail)
where
• class MyMonad m where

-- the methods are not exported!

bind :: m a -> (a -> m b) -> m b

return_ :: a -> m a

fail_ :: String -> m a
• (>>=) :: MyMonad m => m a -> (a -> m b) -> m b

(>>=) = bind

return :: MyMonad m => a -> m a

return = return_

fail :: MyMonad m => String -> m a

fail = fail_
THE PROBLEM WITH ABSTRACT TYPECLASSES
• newtype Foo a = …

instance MyMonad Foo where

{- … what can I write here? 🤔 -}
• Third-party cannot write instances of such classes…
• …without using
• default definitions
• GeneralizedNewtypeDeriving
• …and yes, DerivingVia 😎
USING DerivingVia TO WRITE INSTANCES
• module MyMonad (…, MyMonadV1(..), ImplV1(..)) where
• class MyMonad m where …
• class MyMonadV1 m where

-- public!

bindV1 :: m a -> (a -> m b) -> m b

returnV1 :: a -> m a

failV1 :: String -> m a

failV1 = error
• newtype ImplV1 m a = ImplV1 (m a)
• instance MyMonadV1 m => MyMonad (ImplV1 m) where

-- hypothetical code; needs InstanceSigs to work

bind = coerce (bindV1 @m)

return_ = coerce (returnV1 @m)

fail_ = coerce (failV1 @m)
USING DerivingVia TO WRITE INSTANCES
• Want to write an instance of MyMonad? Use DerivingVia!
• import MyMonad
• newtype Identity a = Identity a

deriving MyMonad

via ImplV1 Identity
• instance MyMonadV1 Identity where

bindV1 (Identity x) f = f x

returnV1 x = Identity x
CHANGING THE CLASS HIERARCHY
• Now suppose you want to refactor MyMonad class
• class Applicative m => MyMonad m where

bind :: m a -> (a -> m b) -> m b
• class MyMonad m => MyMonadFail m where

fail_ :: String -> m a
• Can we avoid breakage?
BREAKAGE CAN BE AVOIDED
• …if we change ImplV1's instances accordingly!
• MyMonadV1 is kept as is!
• instance MyMonadV1 m => Functor (ImplV1 m) where …

instance MyMonadV1 m => Applicative (ImplV1 m) where …

instance MyMonadV1 m => MyMonad (ImplV1 m) where …

instance MyMonadV1 m => MyMonadFail (ImplV1 m) where …
• -- a dirty hack is needed (unfortunately)

instance {-# OVERLAPPABLE #-} MyMonadV1 m => Functor m
where

fmap = liftM

instance {-# OVERLAPPABLE #-} MyMonadV1 m =>
Applicative m where

pure = returnV1; (<*>) = ap
WHEN TO USE THIS TECHNIQUE?
• When writing a new library
• When you are sure that you would want to change details in the future
• My library unboxing-vector uses a technique similar to this:
• class … => Unboxable a where

type Rep a

-- hidden methods:

unboxingFrom :: a -> Rep a

unboxingTo :: Rep a -> a
• Users can use a newtype wrapper to derive an instance of
Unboxable with Generic
I'LL WRITE MORE DETAILS
IN A BLOG (HOPEFULLY
SOON…)

More Related Content

Similar to Abstract typeclasses

10 - Encapsulation(object oriented programming)- java . ppt
10 - Encapsulation(object oriented programming)- java . ppt10 - Encapsulation(object oriented programming)- java . ppt
10 - Encapsulation(object oriented programming)- java . ppt
VhlRddy
 
Csharp4 objects and_types
Csharp4 objects and_typesCsharp4 objects and_types
Csharp4 objects and_types
Abed Bukhari
 

Similar to Abstract typeclasses (19)

Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
 
Java Inheritance
Java InheritanceJava Inheritance
Java Inheritance
 
البرمجة الهدفية بلغة جافا - تعدد الأشكال
البرمجة الهدفية بلغة جافا - تعدد الأشكالالبرمجة الهدفية بلغة جافا - تعدد الأشكال
البرمجة الهدفية بلغة جافا - تعدد الأشكال
 
Refactoring Chapter11
Refactoring Chapter11Refactoring Chapter11
Refactoring Chapter11
 
Explain Classes and methods in java (ch04).ppt
Explain Classes and methods in java (ch04).pptExplain Classes and methods in java (ch04).ppt
Explain Classes and methods in java (ch04).ppt
 
MP in Clojure
MP in ClojureMP in Clojure
MP in Clojure
 
Android course session 3 ( OOP ) part 1
Android course session 3 ( OOP ) part 1Android course session 3 ( OOP ) part 1
Android course session 3 ( OOP ) part 1
 
Computer programming 2 Lesson 15
Computer programming 2  Lesson 15Computer programming 2  Lesson 15
Computer programming 2 Lesson 15
 
04inherit
04inherit04inherit
04inherit
 
10 - Encapsulation(object oriented programming)- java . ppt
10 - Encapsulation(object oriented programming)- java . ppt10 - Encapsulation(object oriented programming)- java . ppt
10 - Encapsulation(object oriented programming)- java . ppt
 
.NET F# Inheritance and operator overloading
.NET F# Inheritance and operator overloading.NET F# Inheritance and operator overloading
.NET F# Inheritance and operator overloading
 
PROGRAMMING IN JAVA
PROGRAMMING IN JAVAPROGRAMMING IN JAVA
PROGRAMMING IN JAVA
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
 
Inheritance and Polymorphism in Oops
Inheritance and Polymorphism in OopsInheritance and Polymorphism in Oops
Inheritance and Polymorphism in Oops
 
A Case Study on Java. Java Presentation
A Case Study on Java. Java Presentation A Case Study on Java. Java Presentation
A Case Study on Java. Java Presentation
 
Csharp4 objects and_types
Csharp4 objects and_typesCsharp4 objects and_types
Csharp4 objects and_types
 
The Next Generation MOP, Jochen Theodorou, GR8Conf 2013
The Next Generation MOP, Jochen Theodorou, GR8Conf 2013 The Next Generation MOP, Jochen Theodorou, GR8Conf 2013
The Next Generation MOP, Jochen Theodorou, GR8Conf 2013
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming Rails
 

Recently uploaded

Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
drm1699
 
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Marc Lester
 

Recently uploaded (20)

BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST API
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
 
Encryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key ConceptsEncryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key Concepts
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
 
architecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfarchitecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdf
 
Software Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringSoftware Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements Engineering
 
Test Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfTest Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdf
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeCon
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test Automation
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfThe Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
 
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined Deck
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdf
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
 
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-CloudAlluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 

Abstract typeclasses

  • 1. ABSTRACT TYPECLASSES — HOW TO DESIGN A FUTURE-PROOF TYPECLASS @mod_poppo 2019-11-09
  • 2. CHANGES TO TYPECLASSES • Functor-Applicative-Monad • Semigroup-Monoid • MonadFail
  • 3. MIGRATION IS PAINFUL • Adding a superclass • data Foo a = …
 instance Monad Foo where …
 -- No instance for Applicative Foo • Removing a method • instance Monad Foo where …
 fail x = …
 -- 'fail' is not a (visible) method of class 'Monad' • Sometimes #ifdef s cannot be avoided 😵
  • 4. ABSTRACT TYPECLASS • A data type whose constructors are hidden is abstract • data Foo = {- hidden -} • A similar concept could be employed to type classes: A type class whose methods are hidden • class Foo a where {- hidden -}
  • 5. AN EXAMPLE OF ABSTRACT TYPECLASS • An example of abstract typeclass is GHC.TypeLits.KnownN at • Its method natSing is hidden • The user can use this class via
 natVal :: KnownNat n => proxy n -> Integer
  • 6. THE MERIT OF BEING ABSTRACT • The author of the class can freely change the definition of the class • e.g. KnownNat has changed its representation since GHC 8.2 (Integer → Natural) • The user doesn't need to care if its representation changed, as long as natVal doesn't change
  • 7. MAKING ‘Monad’ CLASS ABSTRACT • module MyMonad (MyMonad, (>>=), return, fail) where • class MyMonad m where
 -- the methods are not exported!
 bind :: m a -> (a -> m b) -> m b
 return_ :: a -> m a
 fail_ :: String -> m a • (>>=) :: MyMonad m => m a -> (a -> m b) -> m b
 (>>=) = bind
 return :: MyMonad m => a -> m a
 return = return_
 fail :: MyMonad m => String -> m a
 fail = fail_
  • 8. THE PROBLEM WITH ABSTRACT TYPECLASSES • newtype Foo a = …
 instance MyMonad Foo where
 {- … what can I write here? 🤔 -} • Third-party cannot write instances of such classes… • …without using • default definitions • GeneralizedNewtypeDeriving • …and yes, DerivingVia 😎
  • 9. USING DerivingVia TO WRITE INSTANCES • module MyMonad (…, MyMonadV1(..), ImplV1(..)) where • class MyMonad m where … • class MyMonadV1 m where
 -- public!
 bindV1 :: m a -> (a -> m b) -> m b
 returnV1 :: a -> m a
 failV1 :: String -> m a
 failV1 = error • newtype ImplV1 m a = ImplV1 (m a) • instance MyMonadV1 m => MyMonad (ImplV1 m) where
 -- hypothetical code; needs InstanceSigs to work
 bind = coerce (bindV1 @m)
 return_ = coerce (returnV1 @m)
 fail_ = coerce (failV1 @m)
  • 10. USING DerivingVia TO WRITE INSTANCES • Want to write an instance of MyMonad? Use DerivingVia! • import MyMonad • newtype Identity a = Identity a
 deriving MyMonad
 via ImplV1 Identity • instance MyMonadV1 Identity where
 bindV1 (Identity x) f = f x
 returnV1 x = Identity x
  • 11. CHANGING THE CLASS HIERARCHY • Now suppose you want to refactor MyMonad class • class Applicative m => MyMonad m where
 bind :: m a -> (a -> m b) -> m b • class MyMonad m => MyMonadFail m where
 fail_ :: String -> m a • Can we avoid breakage?
  • 12. BREAKAGE CAN BE AVOIDED • …if we change ImplV1's instances accordingly! • MyMonadV1 is kept as is! • instance MyMonadV1 m => Functor (ImplV1 m) where …
 instance MyMonadV1 m => Applicative (ImplV1 m) where …
 instance MyMonadV1 m => MyMonad (ImplV1 m) where …
 instance MyMonadV1 m => MyMonadFail (ImplV1 m) where … • -- a dirty hack is needed (unfortunately)
 instance {-# OVERLAPPABLE #-} MyMonadV1 m => Functor m where
 fmap = liftM
 instance {-# OVERLAPPABLE #-} MyMonadV1 m => Applicative m where
 pure = returnV1; (<*>) = ap
  • 13. WHEN TO USE THIS TECHNIQUE? • When writing a new library • When you are sure that you would want to change details in the future • My library unboxing-vector uses a technique similar to this: • class … => Unboxable a where
 type Rep a
 -- hidden methods:
 unboxingFrom :: a -> Rep a
 unboxingTo :: Rep a -> a • Users can use a newtype wrapper to derive an instance of Unboxable with Generic
  • 14. I'LL WRITE MORE DETAILS IN A BLOG (HOPEFULLY SOON…)