Basic introduction to shapeless HLists,
constructing implicit proofs with them and extending those proofs onto generic product-like types with shapeless.Generic
Code: https://github.com/vpavkin/recursive-implicit-proofs-talk
16. 1 -> Container(Option(Container("a")))
(Int, Container[Option[Container[String]]])
String Container[String] Option[Container[String]]
Container[Option[Container[String]]] (Int, Container[Option[Container[String]]])
A A => B
Ord[T] => Ord[Container[T]]
A => B
Ord[T] => Ord[Option[T]]
A => B
Ord[T] => Ord[Container[T]]
A & B => C
Ord[A] & Ord[B] => Ord[(A,B)]
Int
A
18. Scala List shapeless.HList
Root type List HList
Cons
case class ::[A](
head: A,
tail: List[A])
case class ::[H, T <: HList](
head: H,
tail: T)
Nil Nil (singleton) HNil (singleton)
Type of
1 :: Nil
::[Int] Int :: HNil
Type of
1 :: “a” :: Nil
::[Any] Int :: String :: HNil
Type of
1 :: “a” :: true ::
Nil
::[Any] Int :: String :: Boolean :: HNil
21. case class Person(name: String, age:Int) String :: Int :: HNil
(Int, Boolean) Int :: Boolean :: HNil
•
•
2nd most important property (along with keeping precise types):
25. OddProduct[Int :: String :: Boolean :: Int :: Int :: HNil]
Int :: HNil Boolean :: Int :: Int :: HNil
Int :: String:: Boolean :: Int :: Int :: HNil
A => B
Odd[T <: HList] => Odd[H1 :: H2 :: T]
A => B
Odd[T <: HList] => Odd[H1 :: H2 :: T]
A
Odd[T :: HNil]
Recursive step – resolving to the same implicit def
28. Generic.Aux[T, Repr] – Isomorphism, that
allows us to get Repr from T and vice versa.
Repr – some generic representation of T
Property[Repr] – our Property is proved for
type Repr.
We can (almost always) derive the
Property[T] by converting to/from Repr
and using Property[Repr]
Hint:
Repr here is going to be
an HList
Looks similar to
A & B => C.
Let’s encode the proof!
30. Person(name: String, age: Int)
Int :: HNil
A & B => C
Show[A] & Show[B] => Show[A :: B]
Int
A
Show[Int]
HNil
A
Show[HNil]
String
A
Show[String]
String :: Int :: HNil
A & B => C
Show[A] & Show[B] => Show[A :: B]
Generic.Aux[Person, String :: Int :: HNil]
A (macro)
Generic[T]
Person
A & B => C
Show[R] & Generic.Aux[T,R] => Show[T]
Excited to see so many smart people here
We’re going to play with the dark side of Scala that opens lots of opportunities and powerful tecniques.
There will always be debates, whether it’s applicable to real-life programming or not, but I’ve already seen it being applied with big success and I believe that haters are just afraid to admit they can’t or don’t want to deeper understand the type system
Nothing new from the technical side – just another point of view which shows real beauty of implicits.
Also this section prepares the “proof”-oriented mind set, that will help with the rest of the talk
Theorem here is very very complex – it’s the set of all requirements to our system
So in reality we decompose it in a set of smaller pieces and constructing proofs for each piece.
Compile time and runtime proofs.
Runtime is a difference – when:
compile-time proof is impossible (external inputs) or
impractical (typesystem weakness)
All of these are just simple introductory thoughts to seed the idea.
We will formalize this system a little later and see how exactly you build mathematical proof primitives with implicits
Don’t forget to show the implicit resolution with Shift+Cmd+P
Say that recursion is important feature, that is required for HList based proofs
Will go through basic building blocks, the primitives of proof construction.We’ll also see some differences that arise in the process of comparison
Basic axiom that doesn’t require any other conditions
By chaining several of such blocks we can build proofs of arbitrary length
This one is not restricted to 2 elements – we can require as many conditions as we want to produce a new property
This one is not used often: Only one single proof can be available for any call – having 2 or more is not allowed.This means you must be sure, that if you have several proof rules for the same type, maximum 1 is active in every particular context.
Talk about the reverse order that compiler takes to find the proof
Some of you are familiar with basics of HLists, but to be consistent and sure that everyone is able to understand the following material, I’ll give a short review.
HList difference: Cons has 2 type parameters which allows to store precise type of the tail. In the end HList doesn’t lose any type information at all.
Pure means it doesn’t carry any helpful methods along – only some fact about the type.You won’t see this kind of typeclasses very often, though they can be used. for example to build proofs for phantom types.
Show implicit chain for 5 elements
Show proof step by step
Pure means it doesn’t carry any helpful methods along – only some fact about the type.You won’t see this kind of typeclasses very often, though they can be used. for example to build proofs for phantom types.
Show implicit chain for 5 elements
Show proof step by step
Talk about the reverse order that compiler takes to find the proof
Talk about similarity between recursive HList proofs and math induction
Talk about the reverse order that compiler takes to find the proof
Generic definition
Generic.Aux definition
Example without Aux
Generic definition
Generic.Aux definition
Example without Aux
Generic definition
Generic.Aux definition
Example without Aux