Type level quicksort

Julien Tournay - @skaalf

  • The program expressed in terms of relations, represented as facts and rules.
  • Prolog can run queries over these relations.

Scala is 2 languages

1 runtime language

+

1 compile time language

1 runtime language

+

val a: A
val f: A => B = ???
f(a): B

 A, A ⇒ B ⊢ B

Curry–Howard isomorphism

A proposition is identified with the type of its proofs.

 Peano axioms

 Peano axioms

  • There's a special object called 0. 
    0 is a natural number.
  • For every natural number n,
    there's exactly one other natural number called it's successor.
  • 0 is not the successor of any natural number. All other natural numbers are the successor of a natural number
  • No two natural numbers have the same successor
  • Natural numbers can be compared for equality. Equality is reflexive, symmetric and transitive.
  • For some statement P, P is true for all natural number if:
    • P is true about 0
    • If P is true for a number n,  and P is true for n's successor .
sealed trait Nat
final class Succ[P <: Nat]() extends Nat
final class _0 extends Nat

type _1 = Succ[_0]

type _2 = Succ[_1]

type _3 = Succ[_2]

type _4 = Succ[_3]

type _5 = Succ[_4]

Inequalities

by induction

trait LT[A <: Nat, B <: Nat]

object LT {
    def apply[A <: Nat, B <: Nat]
        (implicit lt: A < B): LT[A, B] = lt

    type <[A <: Nat, B <: Nat] = 
        LT[A, B]

    implicit def lt1[B <: Nat] = 
        new <[_0, Succ[B]] {}

    implicit def lt2[A <: Nat, B <: Nat](implicit lt : A < B) =
        new <[Succ[A], Succ[B]] {}
}
trait LT[A <: Nat, B <: Nat]
implicit def lt1[B <: Nat] = 
    new <[_0, Succ[B]] {}
:t LT.apply[_0, _1]
LT[_0, _1]
implicit def lt2[A <: Nat, B <: Nat]
    (implicit lt : A < B) =
        new <[Succ[A], Succ[B]] {}
:t LT[_1, _5]
LT[_1, _5]

 

:t LT[_2, _1]
<console> error: could not find implicit value for parameter lt: LT.<[_2, _1]

(H)List

sealed trait HList

final class ::[+H, +T <: HList] 
  extends HList

class HNil extends HList
type NS = _1 :: _0 :: _3 :: _2 :: HNil

Quick sort

  • build list of natural numbers 
  • compare natural numbers ✓
  • extract pivot (list head) ✓
  • get all numbers < pivot
  • get all numbers ≥ pivot
  • recursively quick sort
  • concatenate lists 

Induction you will use

trait Sorted[L <: HList] {
    type Out <: HList
}
implicit def hnilSorted: Aux[HNil, HNil] = 
  new Sorted[HNil] { 
    type Out = HNil 
  }
implicit def hlistSorted[...]
    (implicit
      ls: LTEqs.Aux[T, H, lsOut],
      gs: GTs.Aux[T, H, gsOut],
      sortedSmaller: Sorted.Aux[lsOut, smOut],
      sortedLarger: Sorted.Aux[gsOut, slOut],
      preps: Prepend[smOut, H :: slOut]
    ): Aux[H :: T, preps.Out] =
      new Sorted[H :: T] {
        type Out = preps.Out
      }
type NS = _1 :: _0 :: _3 :: _2 :: HNil
:t Sorted[NS]
Sorted.Aux[NS,  _0 :: _1 :: _2 :: _3 :: HNil]

http://jto.github.io/articles/typelevel_quicksort/

Dependent types

Shapeless !!!!

Per Martin-Löf

 Vladimir Voevodsky 

@skaalf​

Scala World 2015

jto.github.io

mandubian.com

@mandubian

21-22 September, Lake District, UK

Made with Slides.com