•1 like•475 views

Report

Share

Download to read offline

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

Follow

- 7. Ordering[A] implicit val intOrdering = new Ordering[Int] {…}
- 8. def sortBy[B](f: A => B) (implicit ord: Ordering[B]) //or def sortBy[B: Ordering](f: A => B) implicit val intOrdering = … implicit def optOrdering[T:Ordering] = new Ordering[Option[T]] { … } // Ok implicitly[Ordering[Option[Int]]] // Can’t prove implicitly[Ordering[Option[String]]]
- 11. // type A = Int implicit val intOrdering: Ordering[Int] = …
- 12. // type B = Option[A] implicit def optOrdering[A] (implicit ev: Ordering[A]): Ordering[Option[A]] = …
- 13. // type C = (A, B) implicit def tuple2Ordering[A, B] (implicit A: Ordering[A], B: Ordering[B]): Ordering[(A, B)] = … implicit def contravariantOrdering[A, B] (implicit C: Converts[A, B], O: Ordering[B]): Ordering[A] =
- 14. implicit def ordered[C <% Comparable[C]]: Ordering[C] = … implicit def comparatorToOrdering[C] (implicit cmp: Comparator[C]): Ordering[C] = … A => C + B => C Avoid ambiguous implicits!
- 15. You can’t ask for an absence of implicit
- 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
- 19. • • • • •
- 20. final class HListOps[L <: HList](l : L) { def at[N <: Nat](implicit at: At[L, N]): at.Out = at(l) } • • • • •
- 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]
- 32. 1. 2. 3. 4. 5.

- 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