Exploring
Type-Level Programming
in Scala
JORGE VÁSQUEZ
SCALA DEVELOPER
Exploring type level programming in Scala
Agenda
● Motivations around Type-Level Programming in Scala
● Background
○ Dependent types
○ Path-dependent types
○ Abstract type members
● Examples of libraries that use Type-Level
Programming
Motivations
around
Type-Level
Programming
Why Type-Level Programming?
● We turn to Scala for type-safety
● But… Sometimes it’s not enough!
Concrete example: Spark DataFrame API
We have lots of potential for runtime bugs!
Concrete example: Spark DataFrame API
df.select(
$"username",
$"tweet"
)
Concrete example: Spark DataFrame API
Error: org.apache.spark.sql.
AnalysisException: cannot
resolve '`username`'
Concrete example: Spark DataFrame API
df.select(
$"timestamp" * 10
)
Concrete example: Spark DataFrame API
Error:
org.apache.spark.sql.
AnalysisException: cannot
resolve '(`timestamp` *
10)' due to data type
mismatch
Concrete example: Spark DataFrame API
df.filter(
$"text" === true
)
// Does not fail
Concrete example: Spark DataFrame API
df.select(
$"text" / 1000
)
// Does not fail
Exploring type level programming in Scala
Can we do better?
Scala has a VERY powerful type system,
why not use it?
Concrete example: Spark with Frameless
Frameless helps us to eliminate a lot of bugs…
At compile time!
Concrete example: Spark with Frameless
tds.select(
tds('username),
tds('tweet)
)
Concrete example: Spark with Frameless
// Error:
No column Symbol with
shapeless.tag.Tagged[Str
ing("username")]
Concrete example: Spark with Frameless
tds.select(
tds('timestamp) * 10
)
Concrete example: Spark with Frameless
// Error:
overloaded method value
* with alternatives
[...] cannot be applied
to (Int)
Concrete example: Spark with Frameless
tds.filter(
tds('text) === true
)
Concrete example: Spark with Frameless
// Error:
overloaded method value
=== with alternatives
[...] cannot be applied
to (Boolean)
Concrete example: Spark with Frameless
tds.select(
tds('text) / 1000
)
Concrete example: Spark with Frameless
// Error:
overloaded method value /
with alternatives [...]
cannot be applied to
(Int)
In conclusion...
Type-level Programming lets you eliminate
bugs at compile-time
In conclusion...
Our focus today: Dependent types
Dependent types are the heart of
Type-Level Programming in Scala
What are
Dependent Types?
What are Dependent Types?
● Dependent Types are types that depend on
values.
● With this, we remove the usual separation
between the type and value worlds.
What are Dependent Types?
● Scala is not a fully dependently typed
language.
● However, it supports some form of
Dependent Types, which is called Path
Dependent Types.
How we define Path Dependent Types?
● In Scala, we can define nested components
● For example, a class inside a trait, a
trait inside a class, etc.
How we define Path Dependent Types?
sealed trait Foo {
sealed trait Bar
}
val foo1 = new Foo {}
val foo2 = new Foo {}
val a: Foo#Bar = new foo1.Bar {} // OK
val b: Foo#Bar = new foo2.Bar {} // OK
val c: foo1.Bar = new foo1.Bar {} // OK
val d: foo2.Bar = new foo1.Bar {}
// Required: foo2.Bar, Found: foo1.Bar
How we define Path Dependent Types?
● Another useful tool is Abstract Type
Members, which are types we don’t know
yet and that we can define later
trait Bar {
type T
}
Example 1: Merging Files
Define a merge function, which should take:
● A list of files
● A merge strategy: Single/Multiple/None
● A callback function: Which should expect:
○ A single file if merge strategy is Single
○ A list of files if merge strategy is Multiple
○ A unit value if merge strategy is None
Example 1: Merging Files
import java.io.File
sealed trait MergeStrategy {
type Output
}
object MergeStrategy {
case object Single extends MergeStrategy { type Output = File }
case object Multiple extends MergeStrategy { type Output = List[File] }
case object None extends MergeStrategy { type Output = Unit }
}
def mergeFiles(files: List[File]): File = ???
Example 1: Merging Files
def merge[T](files: List[File], mergeStrategy: MergeStrategy)
(f: mergeStrategy.Output => T): T =
mergeStrategy match {
case MergeStrategy.Single => f(mergeFiles(files))
case MergeStrategy.Multiple => f(files)
case MergeStrategy.None => f(())
}
Example 1: Merging Files
Example 1: Merging Files
def merge[O, T](
files: List[File],
mergeStrategy: MergeStrategy { type Output = O }
)(f: O => T): T =
mergeStrategy match {
case MergeStrategy.Single => f(mergeFiles(files))
case MergeStrategy.Multiple => f(files)
case MergeStrategy.None => f(())
}
Example 1: Merging Files
val files: List[File] = ???
merge(files, MergeStrategy.Single) { file: File =>
// Do some processing
}
merge(files, MergeStrategy.Multiple) { files: List[File] =>
// Do some processing
}
merge(files, MergeStrategy.None) { _: Unit =>
// Do some processing
}
Example 2: Merging Elements
Define a merge function, which should take:
● A list of elements of any type
● A merge strategy: Single/Multiple/None
● A callback function: Which should expect:
○ A single element if merge strategy is Single
○ A list of elements if merge strategy is Multiple
○ A unit value if merge strategy is None
Example 2: Merging Elements
sealed trait MergeStrategy {
type Output[_]
}
object MergeStrategy {
case object Single extends MergeStrategy { type Output[A] = A }
case object Multiple extends MergeStrategy { type Output[A] = List[A] }
case object None extends MergeStrategy { type Output[_] = Unit }
}
def mergeElements[E](elements: List[E]): E = ???
Example 2: Merging Elements
def merge[E, O[_], T](
elements: List[E],
mergeStrategy: MergeStrategy { type Output[A] = O[A] }
)(f: O[E] => T): T =
mergeStrategy match {
case MergeStrategy.Single => f(mergeElements(elements))
case MergeStrategy.Multiple => f(elements)
case MergeStrategy.None => f(())
}
Example 2: Merging Elements
val messages: List[String] = ???
merge(messages, MergeStrategy.Single) { message: String =>
// Do some processing
}
merge(messages, MergeStrategy.Multiple) { messages: List[String] =>
// Do some processing
}
merge(messages, MergeStrategy.None) { _: Unit =>
// Do some processing
}
In conclusion...
● Path-dependent types are the heart and
soul of Scala's type system
● They help you to improve compile-time type
safety
In conclusion...
DOTTY = DOT Calculus = Path Dependent Types
Some example
libraries
Examples of libraries that use
Type Level Programming
● Shapeless: Generic programming
○ Generic Product Type: HList
○ Generic Sum Type: Coproduct
Examples of libraries that use
Type Level Programming
● Frameless: Expressive types for Spark
Examples of libraries that use
Type Level Programming
● Refined: Refinement types
Examples of libraries that use
Type Level Programming
● ZIO SQL: Type-safe SQL queries
References
● Dependent types in Scala, blog post by Yao Li
● Type Level Programming in Scala step by
step, blog series by Luigi Antonini
● The Type Astronaut’s Guide to Shapeless
Book, by Dave Gurnell
● Introduction to Apache Spark with Frameless,
by Brian Clapper
Special thanks
● To micro sphere.it organizers for hosting this
presentation
● To John De Goes for guidance and support
Thank You!
@jorvasquez2301
jorge.vasquez@scalac.io
jorge-vasquez-2301
Contact me

More Related Content

PDF
A Prelude of Purity: Scaling Back ZIO
PDF
Exploring ZIO Prelude: The game changer for typeclasses in Scala
PDF
Be Smart, Constrain Your Types to Free Your Brain!
PDF
ZIO Prelude - ZIO World 2021
PDF
Scala cheatsheet
PPTX
Scala Back to Basics: Type Classes
PDF
Type classes 101 - classification beyond inheritance
PDF
The Ring programming language version 1.6 book - Part 33 of 189
A Prelude of Purity: Scaling Back ZIO
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Be Smart, Constrain Your Types to Free Your Brain!
ZIO Prelude - ZIO World 2021
Scala cheatsheet
Scala Back to Basics: Type Classes
Type classes 101 - classification beyond inheritance
The Ring programming language version 1.6 book - Part 33 of 189

What's hot (20)

PDF
Scala collections api expressivity and brevity upgrade from java
PPTX
Scala for curious
PPTX
PDF
Property based Testing - generative data & executable domain rules
PDF
Python programming : Classes objects
PDF
First-Class Patterns
PDF
Scala for Jedi
PPT
Spsl v unit - final
PDF
A bit about Scala
PDF
Pragmatic Real-World Scala (short version)
PDF
Getting Started With Scala
PDF
The Ring programming language version 1.5.1 book - Part 31 of 180
KEY
Scala for ruby programmers
PDF
Python programming : Inheritance and polymorphism
ODP
Introducing scala
PDF
Scala collections
PDF
Practical cats
PDF
An introduction to property-based testing
PDF
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
ODP
2.1 Recap From Day One
Scala collections api expressivity and brevity upgrade from java
Scala for curious
Property based Testing - generative data & executable domain rules
Python programming : Classes objects
First-Class Patterns
Scala for Jedi
Spsl v unit - final
A bit about Scala
Pragmatic Real-World Scala (short version)
Getting Started With Scala
The Ring programming language version 1.5.1 book - Part 31 of 180
Scala for ruby programmers
Python programming : Inheritance and polymorphism
Introducing scala
Scala collections
Practical cats
An introduction to property-based testing
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
2.1 Recap From Day One
Ad

Similar to Exploring type level programming in Scala (20)

PDF
Scala: Object-Oriented Meets Functional, by Iulian Dragos
PPTX
PDF
Scala In The Wild
PPT
scala.ppt
PDF
A Brief Introduction to Scala for Java Developers
PDF
Miles Sabin Introduction To Scala For Java Developers
PDF
Is there a perfect data-parallel programming language? (Experiments with More...
PPTX
Types by Adform Research, Saulius Valatka
PDF
From Java to Scala - advantages and possible risks
PDF
Introduction to Scala
PDF
An Introduction to Scala - Blending OO and Functional Paradigms
PDF
Scala - core features
PPT
Scala
PDF
Introduction To Scala
PDF
Scala Paradigms
PDF
Scala or functional programming from a python developer's perspective
PDF
Scala Types of Types @ Lambda Days
PDF
Introduction to Scala : Clueda
PDF
Meet scala
PPTX
Scala training workshop 02
Scala: Object-Oriented Meets Functional, by Iulian Dragos
Scala In The Wild
scala.ppt
A Brief Introduction to Scala for Java Developers
Miles Sabin Introduction To Scala For Java Developers
Is there a perfect data-parallel programming language? (Experiments with More...
Types by Adform Research, Saulius Valatka
From Java to Scala - advantages and possible risks
Introduction to Scala
An Introduction to Scala - Blending OO and Functional Paradigms
Scala - core features
Scala
Introduction To Scala
Scala Paradigms
Scala or functional programming from a python developer's perspective
Scala Types of Types @ Lambda Days
Introduction to Scala : Clueda
Meet scala
Scala training workshop 02
Ad

More from Jorge Vásquez (6)

PDF
Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!
PDF
Programación Funcional 101 con Scala y ZIO 2.0
PDF
Consiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIO
PDF
Functional Programming 101 with Scala and ZIO @FunctionalWorld
PDF
The Terror-Free Guide to Introducing Functional Scala at Work
PDF
Introduction to programming with ZIO functional effects
Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!
Programación Funcional 101 con Scala y ZIO 2.0
Consiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIO
Functional Programming 101 with Scala and ZIO @FunctionalWorld
The Terror-Free Guide to Introducing Functional Scala at Work
Introduction to programming with ZIO functional effects

Recently uploaded (20)

PDF
The Dynamic Duo Transforming Financial Accounting Systems Through Modern Expe...
PDF
PDF-XChange Editor Plus 10.7.0.398.0 Crack Free Download Latest 2025
PDF
How Tridens DevSecOps Ensures Compliance, Security, and Agility
PPTX
Download Adobe Photoshop Crack 2025 Free
PPTX
Lecture 5 Software Requirement Engineering
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PPTX
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
PDF
Visual explanation of Dijkstra's Algorithm using Python
PPTX
Full-Stack Developer Courses That Actually Land You Jobs
DOCX
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
PPTX
Matchmaking for JVMs: How to Pick the Perfect GC Partner
PPTX
Trending Python Topics for Data Visualization in 2025
PPTX
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
PDF
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
PPTX
CNN LeNet5 Architecture: Neural Networks
PPTX
Python is a high-level, interpreted programming language
PDF
Practical Indispensable Project Management Tips for Delivering Successful Exp...
PDF
BoxLang Dynamic AWS Lambda - Japan Edition
PDF
E-Commerce Website Development Companyin india
PPTX
Cybersecurity: Protecting the Digital World
The Dynamic Duo Transforming Financial Accounting Systems Through Modern Expe...
PDF-XChange Editor Plus 10.7.0.398.0 Crack Free Download Latest 2025
How Tridens DevSecOps Ensures Compliance, Security, and Agility
Download Adobe Photoshop Crack 2025 Free
Lecture 5 Software Requirement Engineering
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
Visual explanation of Dijkstra's Algorithm using Python
Full-Stack Developer Courses That Actually Land You Jobs
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
Matchmaking for JVMs: How to Pick the Perfect GC Partner
Trending Python Topics for Data Visualization in 2025
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
CNN LeNet5 Architecture: Neural Networks
Python is a high-level, interpreted programming language
Practical Indispensable Project Management Tips for Delivering Successful Exp...
BoxLang Dynamic AWS Lambda - Japan Edition
E-Commerce Website Development Companyin india
Cybersecurity: Protecting the Digital World

Exploring type level programming in Scala

  • 4. Agenda ● Motivations around Type-Level Programming in Scala ● Background ○ Dependent types ○ Path-dependent types ○ Abstract type members ● Examples of libraries that use Type-Level Programming
  • 6. Why Type-Level Programming? ● We turn to Scala for type-safety ● But… Sometimes it’s not enough!
  • 7. Concrete example: Spark DataFrame API We have lots of potential for runtime bugs!
  • 8. Concrete example: Spark DataFrame API df.select( $"username", $"tweet" )
  • 9. Concrete example: Spark DataFrame API Error: org.apache.spark.sql. AnalysisException: cannot resolve '`username`'
  • 10. Concrete example: Spark DataFrame API df.select( $"timestamp" * 10 )
  • 11. Concrete example: Spark DataFrame API Error: org.apache.spark.sql. AnalysisException: cannot resolve '(`timestamp` * 10)' due to data type mismatch
  • 12. Concrete example: Spark DataFrame API df.filter( $"text" === true ) // Does not fail
  • 13. Concrete example: Spark DataFrame API df.select( $"text" / 1000 ) // Does not fail
  • 15. Can we do better? Scala has a VERY powerful type system, why not use it?
  • 16. Concrete example: Spark with Frameless Frameless helps us to eliminate a lot of bugs… At compile time!
  • 17. Concrete example: Spark with Frameless tds.select( tds('username), tds('tweet) )
  • 18. Concrete example: Spark with Frameless // Error: No column Symbol with shapeless.tag.Tagged[Str ing("username")]
  • 19. Concrete example: Spark with Frameless tds.select( tds('timestamp) * 10 )
  • 20. Concrete example: Spark with Frameless // Error: overloaded method value * with alternatives [...] cannot be applied to (Int)
  • 21. Concrete example: Spark with Frameless tds.filter( tds('text) === true )
  • 22. Concrete example: Spark with Frameless // Error: overloaded method value === with alternatives [...] cannot be applied to (Boolean)
  • 23. Concrete example: Spark with Frameless tds.select( tds('text) / 1000 )
  • 24. Concrete example: Spark with Frameless // Error: overloaded method value / with alternatives [...] cannot be applied to (Int)
  • 25. In conclusion... Type-level Programming lets you eliminate bugs at compile-time
  • 27. Our focus today: Dependent types Dependent types are the heart of Type-Level Programming in Scala
  • 29. What are Dependent Types? ● Dependent Types are types that depend on values. ● With this, we remove the usual separation between the type and value worlds.
  • 30. What are Dependent Types? ● Scala is not a fully dependently typed language. ● However, it supports some form of Dependent Types, which is called Path Dependent Types.
  • 31. How we define Path Dependent Types? ● In Scala, we can define nested components ● For example, a class inside a trait, a trait inside a class, etc.
  • 32. How we define Path Dependent Types? sealed trait Foo { sealed trait Bar } val foo1 = new Foo {} val foo2 = new Foo {} val a: Foo#Bar = new foo1.Bar {} // OK val b: Foo#Bar = new foo2.Bar {} // OK val c: foo1.Bar = new foo1.Bar {} // OK val d: foo2.Bar = new foo1.Bar {} // Required: foo2.Bar, Found: foo1.Bar
  • 33. How we define Path Dependent Types? ● Another useful tool is Abstract Type Members, which are types we don’t know yet and that we can define later trait Bar { type T }
  • 34. Example 1: Merging Files Define a merge function, which should take: ● A list of files ● A merge strategy: Single/Multiple/None ● A callback function: Which should expect: ○ A single file if merge strategy is Single ○ A list of files if merge strategy is Multiple ○ A unit value if merge strategy is None
  • 35. Example 1: Merging Files import java.io.File sealed trait MergeStrategy { type Output } object MergeStrategy { case object Single extends MergeStrategy { type Output = File } case object Multiple extends MergeStrategy { type Output = List[File] } case object None extends MergeStrategy { type Output = Unit } } def mergeFiles(files: List[File]): File = ???
  • 36. Example 1: Merging Files def merge[T](files: List[File], mergeStrategy: MergeStrategy) (f: mergeStrategy.Output => T): T = mergeStrategy match { case MergeStrategy.Single => f(mergeFiles(files)) case MergeStrategy.Multiple => f(files) case MergeStrategy.None => f(()) }
  • 38. Example 1: Merging Files def merge[O, T]( files: List[File], mergeStrategy: MergeStrategy { type Output = O } )(f: O => T): T = mergeStrategy match { case MergeStrategy.Single => f(mergeFiles(files)) case MergeStrategy.Multiple => f(files) case MergeStrategy.None => f(()) }
  • 39. Example 1: Merging Files val files: List[File] = ??? merge(files, MergeStrategy.Single) { file: File => // Do some processing } merge(files, MergeStrategy.Multiple) { files: List[File] => // Do some processing } merge(files, MergeStrategy.None) { _: Unit => // Do some processing }
  • 40. Example 2: Merging Elements Define a merge function, which should take: ● A list of elements of any type ● A merge strategy: Single/Multiple/None ● A callback function: Which should expect: ○ A single element if merge strategy is Single ○ A list of elements if merge strategy is Multiple ○ A unit value if merge strategy is None
  • 41. Example 2: Merging Elements sealed trait MergeStrategy { type Output[_] } object MergeStrategy { case object Single extends MergeStrategy { type Output[A] = A } case object Multiple extends MergeStrategy { type Output[A] = List[A] } case object None extends MergeStrategy { type Output[_] = Unit } } def mergeElements[E](elements: List[E]): E = ???
  • 42. Example 2: Merging Elements def merge[E, O[_], T]( elements: List[E], mergeStrategy: MergeStrategy { type Output[A] = O[A] } )(f: O[E] => T): T = mergeStrategy match { case MergeStrategy.Single => f(mergeElements(elements)) case MergeStrategy.Multiple => f(elements) case MergeStrategy.None => f(()) }
  • 43. Example 2: Merging Elements val messages: List[String] = ??? merge(messages, MergeStrategy.Single) { message: String => // Do some processing } merge(messages, MergeStrategy.Multiple) { messages: List[String] => // Do some processing } merge(messages, MergeStrategy.None) { _: Unit => // Do some processing }
  • 44. In conclusion... ● Path-dependent types are the heart and soul of Scala's type system ● They help you to improve compile-time type safety
  • 45. In conclusion... DOTTY = DOT Calculus = Path Dependent Types
  • 47. Examples of libraries that use Type Level Programming ● Shapeless: Generic programming ○ Generic Product Type: HList ○ Generic Sum Type: Coproduct
  • 48. Examples of libraries that use Type Level Programming ● Frameless: Expressive types for Spark
  • 49. Examples of libraries that use Type Level Programming ● Refined: Refinement types
  • 50. Examples of libraries that use Type Level Programming ● ZIO SQL: Type-safe SQL queries
  • 51. References ● Dependent types in Scala, blog post by Yao Li ● Type Level Programming in Scala step by step, blog series by Luigi Antonini ● The Type Astronaut’s Guide to Shapeless Book, by Dave Gurnell ● Introduction to Apache Spark with Frameless, by Brian Clapper
  • 52. Special thanks ● To micro sphere.it organizers for hosting this presentation ● To John De Goes for guidance and support