SlideShare uma empresa Scribd logo
1 de 29
API design: using type classes
    and dependent types

             Ben Lever
             @bmlever

         ScalaSyd Episode #6
             11 July 2012
What I want
traitComp[A] { ... }

              Specifies the
           “computation” of a
             value of type ‘A’


val ii: Comp[Int] = ...

vali: Int = exec(ii)

                         “Execute” the
                         computation
                        specified by ‘ii’.
What would be cool

val ii: Comp[Int] = ...
valss: Comp[String] = ...



val (i: Int, s: String) = exec(ii, ss)

                                          “Execute” multiple
                                           computations of
                                         different types, then
                                         return “embedded”
                                           types as a tuple.
More generally

valaa: Comp[A] = ...
val bb: Comp[B] = ...
valcc: Comp[C] = ...
valdd: Comp[D] = ...

val (a: A, b: B, c: C, d: D) = exec(aa, bb, cc, dd)


                                                Ability to “execute” many
                                                       computations
                                                simultaneously and return
                                                  all “embedded” values
                                                 together retaining types.
But wait, there’s more
traitIOComp[A] { ... }

             Specifies the “IO
            computation” of a
             value of type ‘A’


val ii: IOComp[Int] = ...
                                                            Err[A]
vali: Err[Int] = exec(ii)                                      ||
                                                       Either[String, A])
        Either return the        “Execute” the IO
        computed value             computation
        or an error string        specified by ‘ii’.
And of course

val ii: IOComp[Int] = ...
valss: IOComp[String] = ...



val (i: Err[Int],
s: Err[String]) = exec(ii, ss)

                                 “Execute” multiple IO
                                    computations of
                                  different types, then
                                  return “embedded”
                                    types as a tuple.
Finally

valaa: Comp[A] = ...
val bb: IOComp[B] = ...
valcc: Comp[C] = ...
valdd: IOComp[D] = ...

val (a: A, b: Err[B], c: C, d: Err[D]) =
exec(aa, bb, cc, dd)


                                           “Execute” a mixture
                                            of normal and IO
                                              computations.
Teaser - the final API



defexec[R](v: R)(implicit runner: Runner[R]): runner.Out
My inspiration
  “Couldn’t you use HLists/KLists for this?”

           Miles Sabin’s Shapeless
               provided much
          direction and inspirations

But … I’m not going to talk about Shapeless 
The tricks



defexec[R](v: R)(implicit runner: Runner[R]): runner.Out

      Tuple                  Type                     Dependent
    sweetness               classes                     types
Trick #1: tuple sweetness

defecho[A](x: A) { prinln(x) }



echo((“good”, 47, true))

echo(“good”, 47, true)     // equivalent
Trick #2: type classes
Get the “size” of an object

size(3) // 3
size(“hello”)// 5
size(false)// 1
...
Size type class
traitSize[T] {
defapply(in: T): Int                         Type class
}

object Size {
defsize[S](v: S)(implicits: Size[S]): Int = s(v)

implicit defIntSize = newSize[Int] {
defapply(in: Int): Int = in
  }
implicit defBoolSize = newSize[Boolean] {
defapply(in: Boolean): Int = 1
                                                          Type class
                                                          instances
  }
implicit defStringSize = newSize[String] {
defapply(in: String): Int = in.length
  }
}
Under the hood
Implicit objects inserted by compiler

size(3)(IntSize)// 3
size(“hello”)(StringSize)// 5
size(false)(BoolSize)// 1
...
Expanding the example
Now, get the “size” of multiple objects at once



size(3, “hello”,false)// (3,5,1)
Runner type class
traitRunner[In, Out] {
defapply(in: In): Out
}

object Runner {
defsize[I, O](v: I)(implicitr: Runner[I, O]): O = r(v)

implicit def Tup1[T1](implicit s1: Size[T1]) =
new Runner[T1, Int] {
defapply(in: T1): Int = s1(in)                                    Referencing
  }                                                                  ‘Size’

implicit def Tup2[T1,T2](implicit s1: Size[T1], s2: Size[T2]) =
new Runner[(T1,T2), (Int,Int)] {
defapply(in: (T1,T2)): (Int,Int) = (s1(in._1), s2(in._2))
  }

implicit def Tup3[T1,T2,T3](implicit s1: Size[T1], ...
Under the hood
Implicit object inserted by compiler



size(3, “hello”,false)
(Tup3
IntSize,
StringSize,
BoolSize))
Aside: type class sugar

defsize[S](v: S)(implicitsizer: Size[S]): Int


is equivalent to
defsize[S : Size](v: S) : Int

                     Type class
                     constraint
‘size’ is easy
Runner instances know output types are always Ints


                    Returns Int


size(3, “hello”,false)// (3,5,1)

      Returns Int                 Returns Int
‘exec’ is harder
Output types are always different

                  Returns               Returns
                   Err[B]                Err[D]


exec(aa, bb, cc, dd)

      Returns A             Returns C
Exec type class
traitExec[In, Out] {
defapply(in: In): Out
}

object Exec {

implicit defcompExec[A] = newExec[Comp[A], A] {
defapply(in: Comp[A]): A = execute(in)
 }

implicit defioCompExec[A] = newExec[IOComp[A], Err[A]] {
defapply(in: IOComp[A]): Err[A] = ioExecute(in)
  }
}
Updated Runner type class
Runner return type is dependent on Exec return type

traitRunner[In, Out] {
defapply(in: In): Out
}

object Runner {
defexec[I,O](v: I)(implicitr: Runner[I,O]): O = r(v)

implicit def Tup1[T1](implicit ex1: Exec[T1,?]) =
new Runner[T1, ?] {
defapply(in: T1): ? = ex1(in)
  }                                               Needs to be
  ...                                           dependent on ex1
It gets worse

implicit def Tup2[T1,T2](implicit ex1: Exec[T1,?],
                      ex2: Exec[T2,?]) =
new Runner[(T1,T2),(?,?)] {
   defapply(in: (T1,T2)): (?,?) = (ex1(in._1),
                        ex2(in._2))
 }

 ...
Trick #3: Dependent types


Dependent types are types where the realization
  of the type created is actually dependent on
           the values being provided.
                                      (SCALABOUND)
Type parameters vs members
 traitExec[In, Out] {           Type
                             parameter
 defapply(in: In): Out
 }

          is equivalent to

 traitExec[In] {
 typeOut                      Type
                             member
 defapply(in: In): Out
 }
Exec using type members
traitExec[In] {
typeOut
defapply(in: In): Out
}

object Exec {

implicit defcompExec[A] = newExec[Comp[A]] {
typeOut = A
defapply(in: Comp[A]): A = execute(in)
  }

implicit defioCompExec[A] = newExec[IOComp[A]] {
typeOut = Err[A]
defapply(in: IOComp[A]): Err[A] = ioExecute(in)
  }
}
Using dependent method types
traitRunner[In] {
typeOut
defapply(in: In): Out                                         Return type is
                                                              dependent on
}
                                                             ‘r’. Access type
                                                              as a member.
object Runner {
defexec[R](v: R)(implicitr: Runner[R]): r.Out = r(v)

implicit def Tup1[T1](implicit ex1: Exec[T1]) =
new Runner[T1] {
typeOut = ex1.Out
defapply(in: T1): ex1.Out = ex1(in)
   }
                                                   Return type is dependent on
   ...                                                  ex1’s return type
And again
implicit def Tup2[T1,T2](implicit ex1: Exec[T1],
                      ex2: Exec[T2]) =
new Runner[(T1,T2)] {
typeOut = (ex1.Out, ex2.Out)
defapply(in: (T1,T2)): Out = (ex1(in._1),
                       ex2(in._2))
  }

 ...
Remember -Y
Dependent method types are still experimental!
        (but “turned-on” in 2.10.x)



        -Ydependent-method-types

Mais conteúdo relacionado

Mais procurados

Testing for share
Testing for share Testing for share
Testing for share Rajeev Mehta
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersHermann Hueck
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
2 kotlin vs. java: what java has that kotlin does not
2  kotlin vs. java: what java has that kotlin does not2  kotlin vs. java: what java has that kotlin does not
2 kotlin vs. java: what java has that kotlin does notSergey Bandysik
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick referenceArduino Aficionado
 
Use Applicative where applicable!
Use Applicative where applicable!Use Applicative where applicable!
Use Applicative where applicable!Hermann Hueck
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Collection v3
Collection v3Collection v3
Collection v3Sunil OS
 

Mais procurados (20)

Testing for share
Testing for share Testing for share
Testing for share
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
C# programming
C# programming C# programming
C# programming
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
OOP v3
OOP v3OOP v3
OOP v3
 
Core C#
Core C#Core C#
Core C#
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad Transformers
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
A taste of Functional Programming
A taste of Functional ProgrammingA taste of Functional Programming
A taste of Functional Programming
 
2 kotlin vs. java: what java has that kotlin does not
2  kotlin vs. java: what java has that kotlin does not2  kotlin vs. java: what java has that kotlin does not
2 kotlin vs. java: what java has that kotlin does not
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick reference
 
Use Applicative where applicable!
Use Applicative where applicable!Use Applicative where applicable!
Use Applicative where applicable!
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Collection v3
Collection v3Collection v3
Collection v3
 
Hammurabi
HammurabiHammurabi
Hammurabi
 

Semelhante a API design for type classes and dependent types

Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoEleanor McHugh
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
Leet Code May Coding Challenge - DataStructure and Algorithm Problems
Leet Code May Coding Challenge - DataStructure and Algorithm ProblemsLeet Code May Coding Challenge - DataStructure and Algorithm Problems
Leet Code May Coding Challenge - DataStructure and Algorithm ProblemsSunil Yadav
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperDeepak Singh
 
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 worldDebasish Ghosh
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2Hang Zhao
 
C# Summer course - Lecture 2
C# Summer course - Lecture 2C# Summer course - Lecture 2
C# Summer course - Lecture 2mohamedsamyali
 
Type classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceAlexey Raga
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and HaskellHermann Hueck
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator PatternEric Torreborre
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objectsHusain Dalal
 
Arrays and structures
Arrays and structuresArrays and structures
Arrays and structuresMohd Arif
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 

Semelhante a API design for type classes and dependent types (20)

Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Leet Code May Coding Challenge - DataStructure and Algorithm Problems
Leet Code May Coding Challenge - DataStructure and Algorithm ProblemsLeet Code May Coding Challenge - DataStructure and Algorithm Problems
Leet Code May Coding Challenge - DataStructure and Algorithm Problems
 
Monadologie
MonadologieMonadologie
Monadologie
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paper
 
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
 
What are monads?
What are monads?What are monads?
What are monads?
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
C# Summer course - Lecture 2
C# Summer course - Lecture 2C# Summer course - Lecture 2
C# Summer course - Lecture 2
 
Type classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritance
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
 
Arrays and structures
Arrays and structuresArrays and structures
Arrays and structures
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
C++11
C++11C++11
C++11
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 

Último

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 

Último (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

API design for type classes and dependent types

  • 1. API design: using type classes and dependent types Ben Lever @bmlever ScalaSyd Episode #6 11 July 2012
  • 2. What I want traitComp[A] { ... } Specifies the “computation” of a value of type ‘A’ val ii: Comp[Int] = ... vali: Int = exec(ii) “Execute” the computation specified by ‘ii’.
  • 3. What would be cool val ii: Comp[Int] = ... valss: Comp[String] = ... val (i: Int, s: String) = exec(ii, ss) “Execute” multiple computations of different types, then return “embedded” types as a tuple.
  • 4. More generally valaa: Comp[A] = ... val bb: Comp[B] = ... valcc: Comp[C] = ... valdd: Comp[D] = ... val (a: A, b: B, c: C, d: D) = exec(aa, bb, cc, dd) Ability to “execute” many computations simultaneously and return all “embedded” values together retaining types.
  • 5. But wait, there’s more traitIOComp[A] { ... } Specifies the “IO computation” of a value of type ‘A’ val ii: IOComp[Int] = ... Err[A] vali: Err[Int] = exec(ii) || Either[String, A]) Either return the “Execute” the IO computed value computation or an error string specified by ‘ii’.
  • 6. And of course val ii: IOComp[Int] = ... valss: IOComp[String] = ... val (i: Err[Int], s: Err[String]) = exec(ii, ss) “Execute” multiple IO computations of different types, then return “embedded” types as a tuple.
  • 7. Finally valaa: Comp[A] = ... val bb: IOComp[B] = ... valcc: Comp[C] = ... valdd: IOComp[D] = ... val (a: A, b: Err[B], c: C, d: Err[D]) = exec(aa, bb, cc, dd) “Execute” a mixture of normal and IO computations.
  • 8. Teaser - the final API defexec[R](v: R)(implicit runner: Runner[R]): runner.Out
  • 9. My inspiration “Couldn’t you use HLists/KLists for this?” Miles Sabin’s Shapeless provided much direction and inspirations But … I’m not going to talk about Shapeless 
  • 10. The tricks defexec[R](v: R)(implicit runner: Runner[R]): runner.Out Tuple Type Dependent sweetness classes types
  • 11. Trick #1: tuple sweetness defecho[A](x: A) { prinln(x) } echo((“good”, 47, true)) echo(“good”, 47, true) // equivalent
  • 12. Trick #2: type classes Get the “size” of an object size(3) // 3 size(“hello”)// 5 size(false)// 1 ...
  • 13. Size type class traitSize[T] { defapply(in: T): Int Type class } object Size { defsize[S](v: S)(implicits: Size[S]): Int = s(v) implicit defIntSize = newSize[Int] { defapply(in: Int): Int = in } implicit defBoolSize = newSize[Boolean] { defapply(in: Boolean): Int = 1 Type class instances } implicit defStringSize = newSize[String] { defapply(in: String): Int = in.length } }
  • 14. Under the hood Implicit objects inserted by compiler size(3)(IntSize)// 3 size(“hello”)(StringSize)// 5 size(false)(BoolSize)// 1 ...
  • 15. Expanding the example Now, get the “size” of multiple objects at once size(3, “hello”,false)// (3,5,1)
  • 16. Runner type class traitRunner[In, Out] { defapply(in: In): Out } object Runner { defsize[I, O](v: I)(implicitr: Runner[I, O]): O = r(v) implicit def Tup1[T1](implicit s1: Size[T1]) = new Runner[T1, Int] { defapply(in: T1): Int = s1(in) Referencing } ‘Size’ implicit def Tup2[T1,T2](implicit s1: Size[T1], s2: Size[T2]) = new Runner[(T1,T2), (Int,Int)] { defapply(in: (T1,T2)): (Int,Int) = (s1(in._1), s2(in._2)) } implicit def Tup3[T1,T2,T3](implicit s1: Size[T1], ...
  • 17. Under the hood Implicit object inserted by compiler size(3, “hello”,false) (Tup3 IntSize, StringSize, BoolSize))
  • 18. Aside: type class sugar defsize[S](v: S)(implicitsizer: Size[S]): Int is equivalent to defsize[S : Size](v: S) : Int Type class constraint
  • 19. ‘size’ is easy Runner instances know output types are always Ints Returns Int size(3, “hello”,false)// (3,5,1) Returns Int Returns Int
  • 20. ‘exec’ is harder Output types are always different Returns Returns Err[B] Err[D] exec(aa, bb, cc, dd) Returns A Returns C
  • 21. Exec type class traitExec[In, Out] { defapply(in: In): Out } object Exec { implicit defcompExec[A] = newExec[Comp[A], A] { defapply(in: Comp[A]): A = execute(in) } implicit defioCompExec[A] = newExec[IOComp[A], Err[A]] { defapply(in: IOComp[A]): Err[A] = ioExecute(in) } }
  • 22. Updated Runner type class Runner return type is dependent on Exec return type traitRunner[In, Out] { defapply(in: In): Out } object Runner { defexec[I,O](v: I)(implicitr: Runner[I,O]): O = r(v) implicit def Tup1[T1](implicit ex1: Exec[T1,?]) = new Runner[T1, ?] { defapply(in: T1): ? = ex1(in) } Needs to be ... dependent on ex1
  • 23. It gets worse implicit def Tup2[T1,T2](implicit ex1: Exec[T1,?], ex2: Exec[T2,?]) = new Runner[(T1,T2),(?,?)] { defapply(in: (T1,T2)): (?,?) = (ex1(in._1), ex2(in._2)) } ...
  • 24. Trick #3: Dependent types Dependent types are types where the realization of the type created is actually dependent on the values being provided. (SCALABOUND)
  • 25. Type parameters vs members traitExec[In, Out] { Type parameter defapply(in: In): Out } is equivalent to traitExec[In] { typeOut Type member defapply(in: In): Out }
  • 26. Exec using type members traitExec[In] { typeOut defapply(in: In): Out } object Exec { implicit defcompExec[A] = newExec[Comp[A]] { typeOut = A defapply(in: Comp[A]): A = execute(in) } implicit defioCompExec[A] = newExec[IOComp[A]] { typeOut = Err[A] defapply(in: IOComp[A]): Err[A] = ioExecute(in) } }
  • 27. Using dependent method types traitRunner[In] { typeOut defapply(in: In): Out Return type is dependent on } ‘r’. Access type as a member. object Runner { defexec[R](v: R)(implicitr: Runner[R]): r.Out = r(v) implicit def Tup1[T1](implicit ex1: Exec[T1]) = new Runner[T1] { typeOut = ex1.Out defapply(in: T1): ex1.Out = ex1(in) } Return type is dependent on ... ex1’s return type
  • 28. And again implicit def Tup2[T1,T2](implicit ex1: Exec[T1], ex2: Exec[T2]) = new Runner[(T1,T2)] { typeOut = (ex1.Out, ex2.Out) defapply(in: (T1,T2)): Out = (ex1(in._1), ex2(in._2)) } ...
  • 29. Remember -Y Dependent method types are still experimental! (but “turned-on” in 2.10.x) -Ydependent-method-types