val a: A val f: A => B = ???
f(a): B
A, A ⇒ B ⊢ B
A proposition is identified with the type of its proofs.
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]
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]
sealed trait HList final class ::[+H, +T <: HList] extends HList class HNil extends HList
type NS = _1 :: _0 :: _3 :: _2 :: HNil
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]
@skaalf
Scala World 2015
jto.github.io
mandubian.com
@mandubian
21-22 September, Lake District, UK