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

New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 

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