SlideShare une entreprise Scribd logo
1  sur  57
Télécharger pour lire hors ligne
Demystifying
Shapeless
Jared Roesch
@roeschinc
https://github.com/jroesch
1
Who I am
2
What I do:
PL Lab
3
What is Shapeless?
• https://github.com/milessabin/shapeless
• A library from Miles Sabin and co.
• A playground for advanced typed FP
4
It has lots of features
5
object size extends Poly1 {
implicit def int = at[Int] (x => 1)
implicit def string = at[String] (s => s.length)
implicit def tuple[A, B] = at[(A, B)] (t => 2)
}
!
val list = 1 :: “foo” :: (‘x’, ‘a’) :: HNil
list.map(size) // => 1 :: 3 :: 2 :: HNil
We can do flexible things like:
6
Inspiration
• Scrap Your Boilerplate
• Generic Deriving in Haskell
• Dependently typed languages
7
Static reasoning
• allows for us to implement powerful compile time
abstractions
• you only pay a minor cost with extra compile time,
and passing around proof terms
8
Type safe casting of an arbitrary List to Product:
9
case class Point(x: Int, y: Int)
val xs: List[Any] = List(1,2)
xs.as[Point]
https://gist.github.com/jroesch/52727c6d77a9d98458d5
scala> val q = sql("select name, age from person")
scala> q() map (_ get "age")
res0: List[Int] = List(36, 14)
compile time checked SQL:
from: https://github.com/jonifreeman/sqltyped
10
Dependent Types
• relaxation of the “phase distinction”
• simply: remove the distinction between types and
values (allow types to depend on values)
• many things billed as type level programming are
attempts at emulating dependent types
11
The phase distinction exists in Scala:
!
Vect : (Nat, Type) => Type
!
we would like to write something like this:
!
trait Vect[N <: Nat, A]
!
we are still writing this:
!
Vect : (Type, Type) => Type
12
Types as Logic
• type systems == logical framework
• types correspond to propositions, and programs to
proofs
• types can be boring (i.e Int, String, User); not all
proofs are interesting
13
How do we emulate
dependent types?
• We still have the phase distinction to get around
• We need to promote values to the type level (i.e 0
can either act as a value or type)
• Vect[0, Int] and val x = 0
14
Nat
• Natural numbers (0, 1 …)
• Let’s look at both the value level and the type level
• We need these to reason about numeric constraints
like size, ordering, indexing, and so on.
• Usually represented by a Zero element and a
Successor function.
15
sealed trait Nat
case object Zero extends Nat
case class Succ(n : Nat) extends Nat
16
A value representing a Natural number:
How do we encode a type level representation of naturals?
17
Prerequisites
‣ implicit arguments
‣ sub-typing, and bounded polymorphism
‣ type members
‣ structural refinement types
‣ path dependent types
18
implicit val x: Int = 10
!
def needsImplicit(implicit ev: Int) = ???
implicit arguments allow us to pass extra parameters
around with help of the compiler:
19
type members allow for values to have type information:
trait User { type Email; val email : Email }
!
20
def userWithEmail[E](e : E) = new User {
type Email = E
val email = e
}
!
21
We make a type part of the value:
val user = userWithEmail(“jroesch@invoca.com”)
val email : user.Email = user.email
!
def takesUser(u: User) =
/* the type of email is hidden here */
22
The type is now existential:
also we make use of structural refinement types:
sealed trait Database
!
sealed trait Postgres extends Database
case object Postgres extends Postgres
!
sealed trait MySQL extends Database
case object MySQL extends MySQL
!
trait DataStore { type DB <: Database … }
23
// Refined type
type PostgreSQL = DataStore { type DB = Postgres }
!
def writeJSONB(ds: PostgreSQL, jsonb: JSONB) = ???
def dontCare(ds: DataStore, …) = ???
!
val postgres: PostgresSQL = new DataStore { … }
!
val otherDataStore = new DataStore { … }
!
writeJSONB(postgres, value) //works
writeJSONB(otherDataStore, value) //fails
24
We can use this to make our type more specific:
trait Unrefined
type Refined = Unrefined { type T = String }
!
implicitly[Refined <:< Unrefined]
25
refined types are subtypes of unrefined types:
trait ObligationFor[N <: Nat]
!
def proof[N <: Nat](implicit ev: ObligationFor[N])
26
we can use this sub-typing rule and type bounds to our
advantage during implicit selection:
vs
def proof(implicit ev: ObligationFor[Nat])
/* Shapeless Typelevel Natural */
trait Nat {
type N <: Nat
}
!
class _0 extends Nat {
type N = _0
}
!
class Succ[P <: Nat]() extends Nat {
type N = Succ[P]
}
27
implicit def intToNat(i: Int): Nat = …
!
val n: Nat = 1
!
type One = n.N // Succ[_0]
28
We can add an implicit conversion for Naturals:
def lessThan(n: Nat, m: Nat): Bool =
match (n, m) {
case (Zero, Succ(_)) =>
true
case (Succ(np), Succ(mp)) =>
lessThan(np, mp)
case (_, _) =>
false
}
How do we translate a value level algorithm to one
that constructs a proof object instead
29
How do we translate this piece of code?
30
trait LessThan[N <: Nat, M <: Nat]
31
Take our proof and translate it to a type:
// Typelevel LessThan
trait LessThan[N <: Nat, M <: Nat]
!
// We need ways to construct our proofs.
implicit def lessThanBase[M <: Nat] =
new LessThan[_0, Succ[M]] {}
!
implicit def lessThanStep[N <: Nat, M <: Nat]
(implicit lessThanN: LessThan[N, M]) =
new LessThan[Succ[N], Succ[M]] {}
!
def lessThan(n : Nat, m : Nat)
(implicit lessThan: LessThan[n.N, m. N]): Boolean =
true
32
HList
sealed trait HList
!
case class ::[+H, +T <: HList](head : H, tail : T)
extends HList
!
sealed trait HNil extends HList
case object HNil extends HNil
33
import shapeless._
!
val xs : Int :: String :: HNil = 1 :: “foo” :: HNil
34
trait IsHCons[L <: HList] {
type H
type T <: HList
def head(l : L) : H
def tail(l : L) : T
}
35
object IsHCons {
…
!
type Aux[L <: HList, Head, Tail <: HList] =
IsHCons[L] { type H = Head; type T = Tail }
!
implicit def hlistIsHCons[Head, Tail <: HList] =
new IsHCons[Head :: Tail] {
type H = Head
type T = Tail
def head(l : Head :: Tail) : H = l.head
def tail(l : Head :: Tail) : T = l.tail
}
}
36
def head(implicit c : IsHCons[L]) : c.H = c.head(l)
!
def tail(implicit c : IsHCons[L]) : c.T = c.tail(l)
We then demand proof when we implement methods on
HList’s:
37
Proofs as black boxes
• Proof objects can be treated as black boxes, we
only need to know what relationship they express,
not proof details.
• We can use shapeless as a standard library of
useful tools.
38
case class Point(x: Int, y: Int)
!
val generic = Generic.Aux[Point, Int :: Int :: HNil] =
Generic[Point]
!
val point = Point(1,2)
!
val list: Int :: Int :: HNil = generic.to(point)
!
assert(generic.from(list) == point)
39
Applying it
• We can build things using many of the same ideas
• typed SQL, JSON with schema, static string
encoding, and plenty of other uses (ex. Spray)
40
41
sealed trait Encoding
…
!
trait EncodedString[E <: Encoding] { … }
…
!
def staticEncoding[E <: Encoding](enc: E, s: String)
= macro StaticEncoding.encodeAs[E]
42
trait Transcode[Initial <: Encoding] {
type Result <: Encoding
!
def transcode(s: EncodedString[Initial]):
EncodedString[Result]
}
43
trait Concatable[Prefix <: Encoding, Suffix <: Encoding] {
type Result <: Encoding
/* Concat is a little verbose, we just ask for
both our strings. */
def concat(s1: EncodedString[Prefix],
s2: EncodedString[Suffix])
/* We get proof that a transcode can happen for both */
(implicit t1: Transcode.Aux[Prefix, Result]
t2: Transcode.Aux[Suffix, Result]):
/* And we get the result */
EncodedString[Result]
}
44
def concat[E1 <: Encoding, E2 <: Encoding]
(s1: EncodedString[E1], s2: EncodedString[E2])
(implicit c: Concatable[E1, E2]) =
c.concat(s1, s2)
An extended example
• Let’s encode a proof that one HList is a subset of
another HList.
• But is it useful?
45
Imagine our own implementation of a SQL DSL:
!
case class User(
id: Id
name: String,
age: Int,
email: String,
deviceId: Long
)
!
// Create Table
SQL.create[User]
!
SQL.insert(
User(1, “Jared”, 21, “jroesch@cs.ucsb.edu”, 1)
)
!
// successful update
SQL.update[User](“id” ->> 1, “age” ->> 22)
!
// fails to compile
SQL.update[User](“id” ->> 1, bogusField” ->> 1337)
!
… // Queries and so on
46
// successful update
SQL.update[User](“id” ->> 1, “age” ->> 22)
!
// fails to compile
SQL.update[User](“id” ->> 1, bogusField” ->> 1337)
47
48
def subList[A](sub: List[A], list: List[A]): Boolean =
(sub, list) match {
case (Nil, _) =>
true
case (x :: xs, y :: ys) if x == y =>
true && subList(xs, ys)
case (subp, first :: remanning) =>
subList(subp, remaining)
}
49
trait SubSeq[Sub <: HList, Super <: HList]
50
object SubSeq extends LowPrioritySubSeq {
type Aux[L <: HList, S <: HList] = SubSeq[L] {
type Sub = S
}
…
}
51
/* Low priority case where we just keep scanning the list. */
trait LowPrioritySubSeq {
implicit def hconsSubSeq[Sub <: HList, SH, ST <: HList]
(implicit subseq: SubSeq.Aux[Sub, ST]) =
new SubSeq[Sub] {
type Sub = SH :: ST
}
}
52
object SubSeq extends LowPrioritySubSeq {
…
/* HNil is a SubSeq of any HList */
implicit def hnilSubSeq[H <: HList] =
new SubSeq[HNil] {
type Sub = H
}
!
…
}
53
object SubSeq extends LowPrioritySubSeq {
…
implicit def hconsSubSeqIso
[H, SH, T <: HList, ST <: HList]
(implicit iso: H =:= SH,
subseq: SubSeq.Aux[T, ST]) =
new SubSeq[H :: T] {
type Sub = SH :: ST
}
}
54
There are few ways to improve upon our last example, I’ll
leave it as a fun puzzle for you.
55
https://gist.github.com/jroesch/db2674d0ef3e49d43154
!
https://github.com/jroesch/scala-by-the-bay-2014
Acknowledgements
• Thanks to Miles Sabin, the PL Lab, Adelbert
Chang, and Pete Cruz.
56
Thank you for your time, questions?
57

Contenu connexe

Tendances

Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform ResearchVasil Remeniuk
 
Practically Functional
Practically FunctionalPractically Functional
Practically Functionaldjspiewak
 
String and string manipulation
String and string manipulationString and string manipulation
String and string manipulationShahjahan Samoon
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scalafanf42
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitTomer Gabel
 
Scala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To KnowScala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To KnowLightbend
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With ScalaTomer Gabel
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesDebasish Ghosh
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with SwiftFatih Nayebi, Ph.D.
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvmIsaias Barroso
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To ScalaPeter Maas
 
Miles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java DevelopersMiles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java DevelopersSkills Matter
 
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Sanjeev_Knoldus
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with framelessMiguel Pérez Pasalodos
 

Tendances (20)

Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
06. haskell type builder
06. haskell type builder06. haskell type builder
06. haskell type builder
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform Research
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
 
Practically Functional
Practically FunctionalPractically Functional
Practically Functional
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Swift Basics
Swift BasicsSwift Basics
Swift Basics
 
String and string manipulation
String and string manipulationString and string manipulation
String and string manipulation
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and Profit
 
Scala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To KnowScala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To Know
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With Scala
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with Swift
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
Miles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java DevelopersMiles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java Developers
 
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
 

En vedette

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 wholeIlan Godik
 
Scala lens: An introduction
Scala lens: An introductionScala lens: An introduction
Scala lens: An introductionKnoldus Inc.
 
Monocleとかいうのがありまして
MonocleとかいうのがありましてMonocleとかいうのがありまして
MonocleとかいうのがありましてNaoki Aoyama
 
Tvi corporate presentation march 2016
Tvi corporate presentation march 2016Tvi corporate presentation march 2016
Tvi corporate presentation march 2016TVI_Pacific
 
B2.2 PROJECT REPORT
B2.2 PROJECT REPORTB2.2 PROJECT REPORT
B2.2 PROJECT REPORTinhumanu
 
Election may 14 2013 30 minute business plan june 11 2012 office suite x
Election may 14 2013 30 minute business plan june 11 2012 office suite xElection may 14 2013 30 minute business plan june 11 2012 office suite x
Election may 14 2013 30 minute business plan june 11 2012 office suite xConstitutionTunnel
 
Case Study by Ramco - uSHAKA MARINE WORLD
Case Study by Ramco - uSHAKA MARINE WORLDCase Study by Ramco - uSHAKA MARINE WORLD
Case Study by Ramco - uSHAKA MARINE WORLDRamco Systems
 
Kreditech - NOAH16 Berlin
Kreditech - NOAH16 BerlinKreditech - NOAH16 Berlin
Kreditech - NOAH16 BerlinNOAH Advisors
 
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...Isla de Tenerife Vívela
 
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...Universidade Federal do Paraná
 
Food and flavor innovation for nutrition and health-Conor Delahunty
Food and flavor innovation for nutrition and health-Conor DelahuntyFood and flavor innovation for nutrition and health-Conor Delahunty
Food and flavor innovation for nutrition and health-Conor DelahuntySimba Events
 
Relapsed AML: Steve Kornblau
Relapsed AML: Steve KornblauRelapsed AML: Steve Kornblau
Relapsed AML: Steve Kornblauspa718
 
Rigupdate Trykk Mai Small
Rigupdate Trykk Mai SmallRigupdate Trykk Mai Small
Rigupdate Trykk Mai SmallEgil Rogne
 

En vedette (20)

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
 
Scala lens: An introduction
Scala lens: An introductionScala lens: An introduction
Scala lens: An introduction
 
Monocleとかいうのがありまして
MonocleとかいうのがありましてMonocleとかいうのがありまして
Monocleとかいうのがありまして
 
Scalaz
ScalazScalaz
Scalaz
 
Definitivonovedades
DefinitivonovedadesDefinitivonovedades
Definitivonovedades
 
Tvi corporate presentation march 2016
Tvi corporate presentation march 2016Tvi corporate presentation march 2016
Tvi corporate presentation march 2016
 
B2.2 PROJECT REPORT
B2.2 PROJECT REPORTB2.2 PROJECT REPORT
B2.2 PROJECT REPORT
 
Election may 14 2013 30 minute business plan june 11 2012 office suite x
Election may 14 2013 30 minute business plan june 11 2012 office suite xElection may 14 2013 30 minute business plan june 11 2012 office suite x
Election may 14 2013 30 minute business plan june 11 2012 office suite x
 
Case Study by Ramco - uSHAKA MARINE WORLD
Case Study by Ramco - uSHAKA MARINE WORLDCase Study by Ramco - uSHAKA MARINE WORLD
Case Study by Ramco - uSHAKA MARINE WORLD
 
Manual de funciones
Manual de funcionesManual de funciones
Manual de funciones
 
Kreditech - NOAH16 Berlin
Kreditech - NOAH16 BerlinKreditech - NOAH16 Berlin
Kreditech - NOAH16 Berlin
 
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...
Descubrimiento y conquista de las islas canarias (1ª edición madrid 7 de sept...
 
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...
COMO SE CONFIGURA A COMUNICAÇÃO ONLINE ENTRE REPRESENTANTES E REPRESENTADOS N...
 
Mc cain y cadena de la papa leopoldo sierra
Mc cain y cadena de la papa leopoldo sierraMc cain y cadena de la papa leopoldo sierra
Mc cain y cadena de la papa leopoldo sierra
 
Coltan
ColtanColtan
Coltan
 
Food and flavor innovation for nutrition and health-Conor Delahunty
Food and flavor innovation for nutrition and health-Conor DelahuntyFood and flavor innovation for nutrition and health-Conor Delahunty
Food and flavor innovation for nutrition and health-Conor Delahunty
 
Relapsed AML: Steve Kornblau
Relapsed AML: Steve KornblauRelapsed AML: Steve Kornblau
Relapsed AML: Steve Kornblau
 
Lectura narcosymaster
Lectura narcosymasterLectura narcosymaster
Lectura narcosymaster
 
Rigupdate Trykk Mai Small
Rigupdate Trykk Mai SmallRigupdate Trykk Mai Small
Rigupdate Trykk Mai Small
 
Israel presentation
Israel presentationIsrael presentation
Israel presentation
 

Similaire à Demystifying Shapeless

Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developersJim Roepcke
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 
C language first program
C language first programC language first program
C language first programNIKHIL KRISHNA
 
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
 
CSharp Language Overview Part 1
CSharp Language Overview Part 1CSharp Language Overview Part 1
CSharp Language Overview Part 1Hossein Zahed
 
Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)Alexander Podkhalyuzin
 
c programming 2nd chapter pdf.PPT
c programming 2nd chapter pdf.PPTc programming 2nd chapter pdf.PPT
c programming 2nd chapter pdf.PPTKauserJahan6
 
A File is a collection of data stored in the secondary memory. So far data wa...
A File is a collection of data stored in the secondary memory. So far data wa...A File is a collection of data stored in the secondary memory. So far data wa...
A File is a collection of data stored in the secondary memory. So far data wa...bhargavi804095
 
Introduction to Problem Solving C Programming
Introduction to Problem Solving C ProgrammingIntroduction to Problem Solving C Programming
Introduction to Problem Solving C ProgrammingRKarthickCSEKIOT
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayUtkarsh Sengar
 
Let’s have some fun with Power Query M language
Let’s have some fun with Power Query M languageLet’s have some fun with Power Query M language
Let’s have some fun with Power Query M languageCédric Charlier
 
Types Working for You, Not Against You
Types Working for You, Not Against YouTypes Working for You, Not Against You
Types Working for You, Not Against YouC4Media
 
Comparing Haskell & Scala
Comparing Haskell & ScalaComparing Haskell & Scala
Comparing Haskell & ScalaMartin Ockajak
 
An Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in PythonAn Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in Pythonyashar Aliabasi
 
Introduction to Type Level Programming
Introduction to Type Level ProgrammingIntroduction to Type Level Programming
Introduction to Type Level ProgrammingYuval Itzchakov
 
Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)Alexander Podkhalyuzin
 
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...ETH Zurich
 

Similaire à Demystifying Shapeless (20)

Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developers
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
C language first program
C language first programC language first program
C language first program
 
C language
C languageC language
C language
 
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
 
CSharp Language Overview Part 1
CSharp Language Overview Part 1CSharp Language Overview Part 1
CSharp Language Overview Part 1
 
Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)
 
Chapter02.PPT
Chapter02.PPTChapter02.PPT
Chapter02.PPT
 
c programming 2nd chapter pdf.PPT
c programming 2nd chapter pdf.PPTc programming 2nd chapter pdf.PPT
c programming 2nd chapter pdf.PPT
 
A File is a collection of data stored in the secondary memory. So far data wa...
A File is a collection of data stored in the secondary memory. So far data wa...A File is a collection of data stored in the secondary memory. So far data wa...
A File is a collection of data stored in the secondary memory. So far data wa...
 
Introduction to Problem Solving C Programming
Introduction to Problem Solving C ProgrammingIntroduction to Problem Solving C Programming
Introduction to Problem Solving C Programming
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
Let’s have some fun with Power Query M language
Let’s have some fun with Power Query M languageLet’s have some fun with Power Query M language
Let’s have some fun with Power Query M language
 
Types Working for You, Not Against You
Types Working for You, Not Against YouTypes Working for You, Not Against You
Types Working for You, Not Against You
 
Comparing Haskell & Scala
Comparing Haskell & ScalaComparing Haskell & Scala
Comparing Haskell & Scala
 
An Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in PythonAn Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in Python
 
Introduction to Type Level Programming
Introduction to Type Level ProgrammingIntroduction to Type Level Programming
Introduction to Type Level Programming
 
Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)
 
Data types
Data typesData types
Data types
 
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
 

Dernier

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 

Dernier (20)

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

Demystifying Shapeless

  • 4. What is Shapeless? • https://github.com/milessabin/shapeless • A library from Miles Sabin and co. • A playground for advanced typed FP 4
  • 5. It has lots of features 5
  • 6. object size extends Poly1 { implicit def int = at[Int] (x => 1) implicit def string = at[String] (s => s.length) implicit def tuple[A, B] = at[(A, B)] (t => 2) } ! val list = 1 :: “foo” :: (‘x’, ‘a’) :: HNil list.map(size) // => 1 :: 3 :: 2 :: HNil We can do flexible things like: 6
  • 7. Inspiration • Scrap Your Boilerplate • Generic Deriving in Haskell • Dependently typed languages 7
  • 8. Static reasoning • allows for us to implement powerful compile time abstractions • you only pay a minor cost with extra compile time, and passing around proof terms 8
  • 9. Type safe casting of an arbitrary List to Product: 9 case class Point(x: Int, y: Int) val xs: List[Any] = List(1,2) xs.as[Point] https://gist.github.com/jroesch/52727c6d77a9d98458d5
  • 10. scala> val q = sql("select name, age from person") scala> q() map (_ get "age") res0: List[Int] = List(36, 14) compile time checked SQL: from: https://github.com/jonifreeman/sqltyped 10
  • 11. Dependent Types • relaxation of the “phase distinction” • simply: remove the distinction between types and values (allow types to depend on values) • many things billed as type level programming are attempts at emulating dependent types 11
  • 12. The phase distinction exists in Scala: ! Vect : (Nat, Type) => Type ! we would like to write something like this: ! trait Vect[N <: Nat, A] ! we are still writing this: ! Vect : (Type, Type) => Type 12
  • 13. Types as Logic • type systems == logical framework • types correspond to propositions, and programs to proofs • types can be boring (i.e Int, String, User); not all proofs are interesting 13
  • 14. How do we emulate dependent types? • We still have the phase distinction to get around • We need to promote values to the type level (i.e 0 can either act as a value or type) • Vect[0, Int] and val x = 0 14
  • 15. Nat • Natural numbers (0, 1 …) • Let’s look at both the value level and the type level • We need these to reason about numeric constraints like size, ordering, indexing, and so on. • Usually represented by a Zero element and a Successor function. 15
  • 16. sealed trait Nat case object Zero extends Nat case class Succ(n : Nat) extends Nat 16 A value representing a Natural number:
  • 17. How do we encode a type level representation of naturals? 17
  • 18. Prerequisites ‣ implicit arguments ‣ sub-typing, and bounded polymorphism ‣ type members ‣ structural refinement types ‣ path dependent types 18
  • 19. implicit val x: Int = 10 ! def needsImplicit(implicit ev: Int) = ??? implicit arguments allow us to pass extra parameters around with help of the compiler: 19
  • 20. type members allow for values to have type information: trait User { type Email; val email : Email } ! 20
  • 21. def userWithEmail[E](e : E) = new User { type Email = E val email = e } ! 21 We make a type part of the value:
  • 22. val user = userWithEmail(“jroesch@invoca.com”) val email : user.Email = user.email ! def takesUser(u: User) = /* the type of email is hidden here */ 22 The type is now existential:
  • 23. also we make use of structural refinement types: sealed trait Database ! sealed trait Postgres extends Database case object Postgres extends Postgres ! sealed trait MySQL extends Database case object MySQL extends MySQL ! trait DataStore { type DB <: Database … } 23
  • 24. // Refined type type PostgreSQL = DataStore { type DB = Postgres } ! def writeJSONB(ds: PostgreSQL, jsonb: JSONB) = ??? def dontCare(ds: DataStore, …) = ??? ! val postgres: PostgresSQL = new DataStore { … } ! val otherDataStore = new DataStore { … } ! writeJSONB(postgres, value) //works writeJSONB(otherDataStore, value) //fails 24 We can use this to make our type more specific:
  • 25. trait Unrefined type Refined = Unrefined { type T = String } ! implicitly[Refined <:< Unrefined] 25 refined types are subtypes of unrefined types:
  • 26. trait ObligationFor[N <: Nat] ! def proof[N <: Nat](implicit ev: ObligationFor[N]) 26 we can use this sub-typing rule and type bounds to our advantage during implicit selection: vs def proof(implicit ev: ObligationFor[Nat])
  • 27. /* Shapeless Typelevel Natural */ trait Nat { type N <: Nat } ! class _0 extends Nat { type N = _0 } ! class Succ[P <: Nat]() extends Nat { type N = Succ[P] } 27
  • 28. implicit def intToNat(i: Int): Nat = … ! val n: Nat = 1 ! type One = n.N // Succ[_0] 28 We can add an implicit conversion for Naturals:
  • 29. def lessThan(n: Nat, m: Nat): Bool = match (n, m) { case (Zero, Succ(_)) => true case (Succ(np), Succ(mp)) => lessThan(np, mp) case (_, _) => false } How do we translate a value level algorithm to one that constructs a proof object instead 29
  • 30. How do we translate this piece of code? 30
  • 31. trait LessThan[N <: Nat, M <: Nat] 31 Take our proof and translate it to a type:
  • 32. // Typelevel LessThan trait LessThan[N <: Nat, M <: Nat] ! // We need ways to construct our proofs. implicit def lessThanBase[M <: Nat] = new LessThan[_0, Succ[M]] {} ! implicit def lessThanStep[N <: Nat, M <: Nat] (implicit lessThanN: LessThan[N, M]) = new LessThan[Succ[N], Succ[M]] {} ! def lessThan(n : Nat, m : Nat) (implicit lessThan: LessThan[n.N, m. N]): Boolean = true 32
  • 33. HList sealed trait HList ! case class ::[+H, +T <: HList](head : H, tail : T) extends HList ! sealed trait HNil extends HList case object HNil extends HNil 33
  • 34. import shapeless._ ! val xs : Int :: String :: HNil = 1 :: “foo” :: HNil 34
  • 35. trait IsHCons[L <: HList] { type H type T <: HList def head(l : L) : H def tail(l : L) : T } 35
  • 36. object IsHCons { … ! type Aux[L <: HList, Head, Tail <: HList] = IsHCons[L] { type H = Head; type T = Tail } ! implicit def hlistIsHCons[Head, Tail <: HList] = new IsHCons[Head :: Tail] { type H = Head type T = Tail def head(l : Head :: Tail) : H = l.head def tail(l : Head :: Tail) : T = l.tail } } 36
  • 37. def head(implicit c : IsHCons[L]) : c.H = c.head(l) ! def tail(implicit c : IsHCons[L]) : c.T = c.tail(l) We then demand proof when we implement methods on HList’s: 37
  • 38. Proofs as black boxes • Proof objects can be treated as black boxes, we only need to know what relationship they express, not proof details. • We can use shapeless as a standard library of useful tools. 38
  • 39. case class Point(x: Int, y: Int) ! val generic = Generic.Aux[Point, Int :: Int :: HNil] = Generic[Point] ! val point = Point(1,2) ! val list: Int :: Int :: HNil = generic.to(point) ! assert(generic.from(list) == point) 39
  • 40. Applying it • We can build things using many of the same ideas • typed SQL, JSON with schema, static string encoding, and plenty of other uses (ex. Spray) 40
  • 41. 41 sealed trait Encoding … ! trait EncodedString[E <: Encoding] { … } … ! def staticEncoding[E <: Encoding](enc: E, s: String) = macro StaticEncoding.encodeAs[E]
  • 42. 42 trait Transcode[Initial <: Encoding] { type Result <: Encoding ! def transcode(s: EncodedString[Initial]): EncodedString[Result] }
  • 43. 43 trait Concatable[Prefix <: Encoding, Suffix <: Encoding] { type Result <: Encoding /* Concat is a little verbose, we just ask for both our strings. */ def concat(s1: EncodedString[Prefix], s2: EncodedString[Suffix]) /* We get proof that a transcode can happen for both */ (implicit t1: Transcode.Aux[Prefix, Result] t2: Transcode.Aux[Suffix, Result]): /* And we get the result */ EncodedString[Result] }
  • 44. 44 def concat[E1 <: Encoding, E2 <: Encoding] (s1: EncodedString[E1], s2: EncodedString[E2]) (implicit c: Concatable[E1, E2]) = c.concat(s1, s2)
  • 45. An extended example • Let’s encode a proof that one HList is a subset of another HList. • But is it useful? 45
  • 46. Imagine our own implementation of a SQL DSL: ! case class User( id: Id name: String, age: Int, email: String, deviceId: Long ) ! // Create Table SQL.create[User] ! SQL.insert( User(1, “Jared”, 21, “jroesch@cs.ucsb.edu”, 1) ) ! // successful update SQL.update[User](“id” ->> 1, “age” ->> 22) ! // fails to compile SQL.update[User](“id” ->> 1, bogusField” ->> 1337) ! … // Queries and so on 46
  • 47. // successful update SQL.update[User](“id” ->> 1, “age” ->> 22) ! // fails to compile SQL.update[User](“id” ->> 1, bogusField” ->> 1337) 47
  • 48. 48 def subList[A](sub: List[A], list: List[A]): Boolean = (sub, list) match { case (Nil, _) => true case (x :: xs, y :: ys) if x == y => true && subList(xs, ys) case (subp, first :: remanning) => subList(subp, remaining) }
  • 49. 49 trait SubSeq[Sub <: HList, Super <: HList]
  • 50. 50 object SubSeq extends LowPrioritySubSeq { type Aux[L <: HList, S <: HList] = SubSeq[L] { type Sub = S } … }
  • 51. 51 /* Low priority case where we just keep scanning the list. */ trait LowPrioritySubSeq { implicit def hconsSubSeq[Sub <: HList, SH, ST <: HList] (implicit subseq: SubSeq.Aux[Sub, ST]) = new SubSeq[Sub] { type Sub = SH :: ST } }
  • 52. 52 object SubSeq extends LowPrioritySubSeq { … /* HNil is a SubSeq of any HList */ implicit def hnilSubSeq[H <: HList] = new SubSeq[HNil] { type Sub = H } ! … }
  • 53. 53 object SubSeq extends LowPrioritySubSeq { … implicit def hconsSubSeqIso [H, SH, T <: HList, ST <: HList] (implicit iso: H =:= SH, subseq: SubSeq.Aux[T, ST]) = new SubSeq[H :: T] { type Sub = SH :: ST } }
  • 54. 54 There are few ways to improve upon our last example, I’ll leave it as a fun puzzle for you.
  • 56. Acknowledgements • Thanks to Miles Sabin, the PL Lab, Adelbert Chang, and Pete Cruz. 56
  • 57. Thank you for your time, questions? 57