SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
Type classes 101
Classification beyond inheritance
Alexey Raga
String
Int
List[Boolean]
case class Name(value: String)
case class Age(value: Int)
case class Person(name: Name, age: Age)
case class Gang(leader: Person, members: List[Person])
Types classify data
String
Int
List[Boolean]
case class Name(value: String)
case class Age(value: Int)
case class Person(name: Name, age: Age)
case class Gang(leader: Person, members: List[Person])
Types classify data
public class Person
implements ISerialisable
{
public String name;
public String address;
...
}
public void saveToDisk(ISerialisable obj) { … }
Types classify data
Types classify data
public class Person
implements ISerialisable, IJsonSerialisable, IXmlSerialisable, IPrettyPrint
{
public String name;
public String address;
...
}
Expression problem
trait Expr
case class Lit(value: Int) extends Expr
case class Add(x: Expr, y: Expr) extends Expr
val expr = Add(Lit(15), Lit(6))
Expression problem
● Operation extension
add new operations: eval, prettyPrint, etc.
● Data extension
add new expressions: Mul, Pow, Neg, ec.
● Static type safety
no isInstanceOf / asInstanceOf
Expression problem
● Operation extension
add new operations: eval, prettyPrint, etc.
● Data extension
add new expressions: Mul, Pow, Neg, ec.
● Static type safety
no isInstanceOf / asInstanceOf
Expression problem
trait Expr {
def eval: Int
def print: String
}
case class Lit(value: Int) extends Expr {
def eval = ???
def print = ???
}
case class Add(x: Expr, y: Expr) extends Expr {
def eval = ???
def print = ???
}
Expression problem
trait Expr {
def eval: Int = this match {
case Lit => ???
case Add => ???
}
def print: String = this match {
case Lit => ???
case Add => ???
}
}
case class Lit(value: Int) extends Expr
case class Add(x: Expr, y: Expr) extends Expr
We can do better
Classification
Plants Animals
?
Classification
Fungi
Classification
Classification
Classification
Classifying types
trait Serialisable[A] {
def serialise(obj: A) : Array[Byte]
}
object PersonSerialisable extends Serialisable[Person] {
def serialise(obj: Person): Array[Byte] = ???
}
def saveToDisk[A](obj: A, ser: Serialisable[A]) = {
val data = ser.serialise(obj)
???
}
saveToDisk(Person("john", 99), PersonSerialisable)
Type classes classify types
trait Serialisable[A] {
def serialise(obj: A) : Array[Byte]
}
implicit object PersonSerialisable extends Serialisable[Person] {
def serialise(obj: Person): Array[Byte] = ???
}
def saveToDisk[A](obj: A)(implicit ser: Serialisable[A]) = {
val data = ser.serialise(obj)
???
}
saveToDisk(Person("john", 99))
Type classes classify types
// already defined in Scala
// def implicitly[T](implicit e: T) = e
def saveToDisk[A: Serialisable](obj: A) = {
val ser = implicitly[Serialisable[A]]
val data = ser.serialise(obj)
...
}
saveToDisk(Person("john", 99))
Testimony ;)
Just saying...
import serialisation.json._
//import serialisation.csv._
//import serialisation.xml._
def saveToDisk[A](obj: A)(implicit ser: Serialisable[A]) = {
val data = ser.serialise(obj)
???
}
saveToDisk(Person("john", 99))
Type classes in Scala
trait Ordering[T] {
def compare(x : T, y : T) : Int
def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0
def gteq(x : T, y : T) : Boolean = compare(x, y) => 0
...
}
trait Numeric[T] extends Ordering[T] {
def plus(x : T, y : T) : T
def minus(x : T, y : T) : T
def negate(x : T) : T
...
}
Type classes in Scala
trait Ordering[T] {
def compare(x : T, y : T) : Int
def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0
def gteq(x : T, y : T) : Boolean = compare(x, y) => 0
}
trait Numeric[T] extends Ordering[T] {
def plus(x : T, y : T) : T
def minus(x : T, y : T) : T
def negate(x : T) : T
}
trait TraversableOnce[+A] {
def sum[B >: A](implicit num : scala.Numeric[B]) : B = ???
def min[B >: A](implicit cmp : scala.Ordering[B]) : A = ???
def max[B >: A](implicit cmp : scala.Ordering[B]) : A = ???
}
Type classes in Scala
trait Ordering[T] {
def compare(x : T, y : T) : Int
def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0
def gteq(x : T, y : T) : Boolean = compare(x, y) => 0
}
trait Numeric[T] extends Ordering[T] {
def plus(x : T, y : T) : T
def minus(x : T, y : T) : T
def negate(x : T) : T
}
trait TraversableOnce[+A] {
def sum[B >: A](implicit num : scala.Numeric[B]) : B = ???
def min[B >: A](implicit cmp : scala.Ordering[B]) : A = ???
def max[B >: A](implicit cmp : scala.Ordering[B]) : A = ???
}
val sum = List(1,2,3).sum
val min = List(1,2,3).min
Type classes in Scalaz
trait Equal[A] {
def equal(a1 : A, a2 : A) : Boolean
}
trait Show[A] {
def shows(a : A) : String
}
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
trait Semigroup[A] {
def append(a1 : A, a2 : => A) : A
}
trait Monoid[A] extends Semigroup[A] {
def zero : A
}
Deriving proofs
//tuple of Equals is also an Equal
implicit def tuple2Equal[A: Equal, B: Equal]: Equal[(A, B)] =
new Equal[(A, B)] {
def equal(a1: (A, B), a2: (A, B)) : Boolean =
a1._1 === a2._1 && a1._2 === a2._2
}
//tuple of Semigroups is also a Semigroup
implicit def tuple2Semigroup[A: Semigroup, B: Semigroup]: Semigroup[(A, B)] = {
new Semigroup[(A, B)] {
def append(p1: (A, B), p2: => (A, B)) =
((p1._1 |+| p2._1), (p1._2 |+| p2._2))
}
}
Expression problem
package ep
trait Expr
case class Lit(value: Int) extends Expr
case class Add[A <: Expr, B <: Expr](x: A, y: B) extends Expr
Expression problem
● Operation extension
add new operations: eval, prettyPrint, etc.
● Data extension
add new expressions: Mul, Pow, Neg, ec.
● Static type safety
no isInstanceOf / asInstanceOf
Expression problem
package ep.evaluate
import ep._
trait Eval[A <: Expr] {
def eval(expr: A) : Int
}
object Eval {
def evaluate[A <: Expr](expr: A)(implicit evA: Eval[A]) = evA.eval(expr)
implicit object LitEval extends Eval[Lit] { def eval(expr: Lit) = expr.value }
implicit def addEval[A <: Expr, B <: Expr](implicit evA: Eval[A], evB: Eval[B]) = {
new Eval[Add[A, B]] {
def eval(expr: Add[A, B]) = evA.eval(expr.x) + evB.eval(expr.y)
}
}
}
Expression problem
package ep
import evaluate._
Eval.evaluate( Add(Lit(15), Lit(6)) ) === 21
Expression problem
package ep.expressions
import ep._
import evaluate._
case class Mul[A <: Expr, B <: Expr](x: A, y: B) extends Expr
object Mul {
implicit def mulEval[A <: Expr, B <: Expr](implicit evA: Eval[A], evB: Eval[B]) = {
new Eval[Mul[A, B]] {
def eval(expr: Mul[A, B]) = evA.eval(expr.x) * evB.eval(expr.y)
}
}
}
Expression problem
import evaluate._
import expressions._
Eval.evaluate( Mul(Lit(2), Add(Lit(15), Lit(6))) ) === 42
Expression problem
package ep.operations
import ep._
import ep.expressions._
trait PPrint[A <: Expr] {
def print(expr: A) : String
}
object PPrint {
def prettyPrint[A <: Expr](expr: A)(implicit pa: PPrint[A]) = pa.print(expr)
implicit object LitPrint extends PPrint[Lit] {
def print(expr: Lit) = expr.value.toString
}
implicit def mulPrint[A <: Expr, B <: Expr](implicit pA: PPrint[A], pB: PPrint[B]) = {
new PPrint[Mul[A, B]] {
def print(expr: Mul[A, B]) = pA.print(expr.x) + " * " + pB.print(expr.y)
}
}
Expression problem
import expressions._
import operations._
import evaluate._
PPrint.prettyPrint( Mul(Lit(2), Add(Lit(15), Lit(6))) ) === "2 * (15 + 6) = 42"
Expression problem
● Operation extension
add new operations: eval, prettyPrint, etc.
● Data extension
add new expressions: Mul, Pow, Neg, ec.
● Static type safety
no isInstanceOf / asInstanceOf
● Add behaviours retroactively
No need to change existing data types
● Solution to the Expression problem
Operation and data extension with static type safety
● Different kinds of operations
“instance” (A => String), “factory” (String => A), etc.
What about us?
Isn't it enough?
No we're not in paradise
This is who we are
This is what we've got
No it's not our paradise

Weitere ähnliche Inhalte

Was ist angesagt?

JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
PROIDEA
 

Was ist angesagt? (20)

JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト
 
JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
 
Beyond Scala Lens
Beyond Scala LensBeyond Scala Lens
Beyond Scala Lens
 
λ | Lenses
λ | Lensesλ | Lenses
λ | Lenses
 
Scalaz
ScalazScalaz
Scalaz
 
Hammurabi
HammurabiHammurabi
Hammurabi
 
Optics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the wholeOptics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the whole
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Scala collection
Scala collectionScala collection
Scala collection
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FP
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210
 
Collections In Scala
Collections In ScalaCollections In Scala
Collections In Scala
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Scala for ruby programmers
Scala for ruby programmersScala for ruby programmers
Scala for ruby programmers
 

Andere mochten auch (7)

Pixel Perfect Precision Handbook (Graphic E-book)
Pixel Perfect Precision Handbook (Graphic E-book)Pixel Perfect Precision Handbook (Graphic E-book)
Pixel Perfect Precision Handbook (Graphic E-book)
 
Perfect pixel
Perfect pixelPerfect pixel
Perfect pixel
 
Type classification-ebook
Type classification-ebookType classification-ebook
Type classification-ebook
 
Scientific table type classification in digital library (DocEng 2012)
Scientific table type classification in digital library (DocEng 2012)Scientific table type classification in digital library (DocEng 2012)
Scientific table type classification in digital library (DocEng 2012)
 
The shape-of-design
The shape-of-designThe shape-of-design
The shape-of-design
 
The pirate book
The pirate bookThe pirate book
The pirate book
 
Chs basic tools and equipment
Chs basic tools and equipmentChs basic tools and equipment
Chs basic tools and equipment
 

Ähnlich wie Type classes 101 - classification beyond inheritance

High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
djspiewak
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Scala-对Java的修正和超越
Scala-对Java的修正和超越Scala-对Java的修正和超越
Scala-对Java的修正和超越
Caoyuan Deng
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 

Ähnlich wie Type classes 101 - classification beyond inheritance (20)

High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Scala
ScalaScala
Scala
 
Scala-对Java的修正和超越
Scala-对Java的修正和超越Scala-对Java的修正和超越
Scala-对Java的修正和超越
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
Monadologie
MonadologieMonadologie
Monadologie
 

Kürzlich hochgeladen

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 

Kürzlich hochgeladen (20)

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 

Type classes 101 - classification beyond inheritance

  • 1. Type classes 101 Classification beyond inheritance Alexey Raga
  • 2. String Int List[Boolean] case class Name(value: String) case class Age(value: Int) case class Person(name: Name, age: Age) case class Gang(leader: Person, members: List[Person]) Types classify data
  • 3. String Int List[Boolean] case class Name(value: String) case class Age(value: Int) case class Person(name: Name, age: Age) case class Gang(leader: Person, members: List[Person]) Types classify data
  • 4. public class Person implements ISerialisable { public String name; public String address; ... } public void saveToDisk(ISerialisable obj) { … } Types classify data
  • 5. Types classify data public class Person implements ISerialisable, IJsonSerialisable, IXmlSerialisable, IPrettyPrint { public String name; public String address; ... }
  • 6. Expression problem trait Expr case class Lit(value: Int) extends Expr case class Add(x: Expr, y: Expr) extends Expr val expr = Add(Lit(15), Lit(6))
  • 7. Expression problem ● Operation extension add new operations: eval, prettyPrint, etc. ● Data extension add new expressions: Mul, Pow, Neg, ec. ● Static type safety no isInstanceOf / asInstanceOf
  • 8. Expression problem ● Operation extension add new operations: eval, prettyPrint, etc. ● Data extension add new expressions: Mul, Pow, Neg, ec. ● Static type safety no isInstanceOf / asInstanceOf
  • 9. Expression problem trait Expr { def eval: Int def print: String } case class Lit(value: Int) extends Expr { def eval = ??? def print = ??? } case class Add(x: Expr, y: Expr) extends Expr { def eval = ??? def print = ??? }
  • 10. Expression problem trait Expr { def eval: Int = this match { case Lit => ??? case Add => ??? } def print: String = this match { case Lit => ??? case Add => ??? } } case class Lit(value: Int) extends Expr case class Add(x: Expr, y: Expr) extends Expr
  • 11. We can do better
  • 17. Classifying types trait Serialisable[A] { def serialise(obj: A) : Array[Byte] } object PersonSerialisable extends Serialisable[Person] { def serialise(obj: Person): Array[Byte] = ??? } def saveToDisk[A](obj: A, ser: Serialisable[A]) = { val data = ser.serialise(obj) ??? } saveToDisk(Person("john", 99), PersonSerialisable)
  • 18. Type classes classify types trait Serialisable[A] { def serialise(obj: A) : Array[Byte] } implicit object PersonSerialisable extends Serialisable[Person] { def serialise(obj: Person): Array[Byte] = ??? } def saveToDisk[A](obj: A)(implicit ser: Serialisable[A]) = { val data = ser.serialise(obj) ??? } saveToDisk(Person("john", 99))
  • 19. Type classes classify types // already defined in Scala // def implicitly[T](implicit e: T) = e def saveToDisk[A: Serialisable](obj: A) = { val ser = implicitly[Serialisable[A]] val data = ser.serialise(obj) ... } saveToDisk(Person("john", 99))
  • 21.
  • 22.
  • 23. Just saying... import serialisation.json._ //import serialisation.csv._ //import serialisation.xml._ def saveToDisk[A](obj: A)(implicit ser: Serialisable[A]) = { val data = ser.serialise(obj) ??? } saveToDisk(Person("john", 99))
  • 24. Type classes in Scala trait Ordering[T] { def compare(x : T, y : T) : Int def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0 def gteq(x : T, y : T) : Boolean = compare(x, y) => 0 ... } trait Numeric[T] extends Ordering[T] { def plus(x : T, y : T) : T def minus(x : T, y : T) : T def negate(x : T) : T ... }
  • 25. Type classes in Scala trait Ordering[T] { def compare(x : T, y : T) : Int def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0 def gteq(x : T, y : T) : Boolean = compare(x, y) => 0 } trait Numeric[T] extends Ordering[T] { def plus(x : T, y : T) : T def minus(x : T, y : T) : T def negate(x : T) : T } trait TraversableOnce[+A] { def sum[B >: A](implicit num : scala.Numeric[B]) : B = ??? def min[B >: A](implicit cmp : scala.Ordering[B]) : A = ??? def max[B >: A](implicit cmp : scala.Ordering[B]) : A = ??? }
  • 26. Type classes in Scala trait Ordering[T] { def compare(x : T, y : T) : Int def lteq(x : T, y : T) : Boolean = compare(x, y) <= 0 def gteq(x : T, y : T) : Boolean = compare(x, y) => 0 } trait Numeric[T] extends Ordering[T] { def plus(x : T, y : T) : T def minus(x : T, y : T) : T def negate(x : T) : T } trait TraversableOnce[+A] { def sum[B >: A](implicit num : scala.Numeric[B]) : B = ??? def min[B >: A](implicit cmp : scala.Ordering[B]) : A = ??? def max[B >: A](implicit cmp : scala.Ordering[B]) : A = ??? } val sum = List(1,2,3).sum val min = List(1,2,3).min
  • 27. Type classes in Scalaz trait Equal[A] { def equal(a1 : A, a2 : A) : Boolean } trait Show[A] { def shows(a : A) : String } trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } trait Semigroup[A] { def append(a1 : A, a2 : => A) : A } trait Monoid[A] extends Semigroup[A] { def zero : A }
  • 28. Deriving proofs //tuple of Equals is also an Equal implicit def tuple2Equal[A: Equal, B: Equal]: Equal[(A, B)] = new Equal[(A, B)] { def equal(a1: (A, B), a2: (A, B)) : Boolean = a1._1 === a2._1 && a1._2 === a2._2 } //tuple of Semigroups is also a Semigroup implicit def tuple2Semigroup[A: Semigroup, B: Semigroup]: Semigroup[(A, B)] = { new Semigroup[(A, B)] { def append(p1: (A, B), p2: => (A, B)) = ((p1._1 |+| p2._1), (p1._2 |+| p2._2)) } }
  • 29.
  • 30. Expression problem package ep trait Expr case class Lit(value: Int) extends Expr case class Add[A <: Expr, B <: Expr](x: A, y: B) extends Expr
  • 31. Expression problem ● Operation extension add new operations: eval, prettyPrint, etc. ● Data extension add new expressions: Mul, Pow, Neg, ec. ● Static type safety no isInstanceOf / asInstanceOf
  • 32. Expression problem package ep.evaluate import ep._ trait Eval[A <: Expr] { def eval(expr: A) : Int } object Eval { def evaluate[A <: Expr](expr: A)(implicit evA: Eval[A]) = evA.eval(expr) implicit object LitEval extends Eval[Lit] { def eval(expr: Lit) = expr.value } implicit def addEval[A <: Expr, B <: Expr](implicit evA: Eval[A], evB: Eval[B]) = { new Eval[Add[A, B]] { def eval(expr: Add[A, B]) = evA.eval(expr.x) + evB.eval(expr.y) } } }
  • 33. Expression problem package ep import evaluate._ Eval.evaluate( Add(Lit(15), Lit(6)) ) === 21
  • 34. Expression problem package ep.expressions import ep._ import evaluate._ case class Mul[A <: Expr, B <: Expr](x: A, y: B) extends Expr object Mul { implicit def mulEval[A <: Expr, B <: Expr](implicit evA: Eval[A], evB: Eval[B]) = { new Eval[Mul[A, B]] { def eval(expr: Mul[A, B]) = evA.eval(expr.x) * evB.eval(expr.y) } } }
  • 35. Expression problem import evaluate._ import expressions._ Eval.evaluate( Mul(Lit(2), Add(Lit(15), Lit(6))) ) === 42
  • 36. Expression problem package ep.operations import ep._ import ep.expressions._ trait PPrint[A <: Expr] { def print(expr: A) : String } object PPrint { def prettyPrint[A <: Expr](expr: A)(implicit pa: PPrint[A]) = pa.print(expr) implicit object LitPrint extends PPrint[Lit] { def print(expr: Lit) = expr.value.toString } implicit def mulPrint[A <: Expr, B <: Expr](implicit pA: PPrint[A], pB: PPrint[B]) = { new PPrint[Mul[A, B]] { def print(expr: Mul[A, B]) = pA.print(expr.x) + " * " + pB.print(expr.y) } }
  • 37. Expression problem import expressions._ import operations._ import evaluate._ PPrint.prettyPrint( Mul(Lit(2), Add(Lit(15), Lit(6))) ) === "2 * (15 + 6) = 42"
  • 38. Expression problem ● Operation extension add new operations: eval, prettyPrint, etc. ● Data extension add new expressions: Mul, Pow, Neg, ec. ● Static type safety no isInstanceOf / asInstanceOf
  • 39. ● Add behaviours retroactively No need to change existing data types ● Solution to the Expression problem Operation and data extension with static type safety ● Different kinds of operations “instance” (A => String), “factory” (String => A), etc.
  • 40.
  • 41.
  • 42. What about us? Isn't it enough? No we're not in paradise This is who we are This is what we've got No it's not our paradise