Last active
          September 25, 2023 01:10 
        
      - 
      
- 
        Save jto/a9b288d5f613a1031789 to your computer and use it in GitHub Desktop. 
    Typelevel quicksort article
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | sealed trait Nat | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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]] {} | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def lt1[B <: Nat] = new <[_0, Succ[B]] {} | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t LT[_0, _1] | |
| LT[_0, _1] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def lt2[A <: Nat, B <: Nat](implicit lt : A < B) = new <[Succ[A], Succ[B]] {} | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t LT[_1, _2] | |
| LT[_1, _2] | |
| // 1 < 2 | |
| :t LT[_2, _1] | |
| <console>:16: error: could not find implicit value for parameter lt: LT.<[_2, _1] | |
| LT[_2, _1] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait LTEq[A <: Nat, B <: Nat] | |
| object LTEq { | |
| def apply[A <: Nat, B <: Nat](implicit lteq: A <= B): LTEq[A, B] = lteq | |
| type <=[A <: Nat, B <: Nat] = LTEq[A, B] | |
| implicit def ltEq1 = new <=[_0, _0] {} | |
| implicit def ltEq2[B <: Nat] = new <=[_0, Succ[B]] {} | |
| implicit def ltEq3[A <: Nat, B <: Nat](implicit lteq : A <= B) = new <=[Succ[A], Succ[B]] {} | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | sealed abstract class List[+A] | |
| case object Nil extends List[Nothing] | |
| final case class ::[B](head: B, tail: List[B]) extends List[B] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | sealed trait HList | |
| final class ::[+H, +T <: HList] extends HList | |
| final class HNil extends HList | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | type NS = _1 :: _0 :: _3 :: _2 :: HNil | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait LTEqs[H <: HList, A <: Nat] { | |
| type Out <: HList | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | final class _0 extends Nat | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def hnilLTEqs[A <: Nat]: Aux[HNil, A, HNil] = | |
| new LTEqs[HNil, A] { type Out = HNil } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def hlistLTEqsLower[A <: Nat, H <: Nat, T <: HList](implicit lts : LTEqs[T, A], l: H <= A): Aux[H :: T, A, H :: lts.Out] = | |
| new LTEqs[H :: T, A] { type Out = H :: lts.Out } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def hlistLTEqsGreater[A <: Nat, H <: Nat, T <: HList](implicit lts : LTEqs[T, A], l: A < H): Aux[H :: T, A, lts.Out] = | |
| new LTEqs[H :: T, A] { type Out = lts.Out } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t LTEqs[_1 :: _0 :: _3 :: _2 :: HNil, _2] | |
| LTEqs.Aux[_1 :: _0 :: _3 :: _2 :: HNil, _2, _1 :: _0 :: _2 : HNil] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait GTs[H <: HList, A <: Nat] { | |
| type Out <: HList | |
| } | |
| object GTs { | |
| import LT._ | |
| import LTEq._ | |
| type Aux[H <: HList, A <: Nat, Out0 <: HList] = GTs[H, A] { type Out = Out0 } | |
| def apply[H <: HList, A <: Nat](implicit lts: GTs[H, A]): Aux[H, A, lts.Out] = lts | |
| implicit def hnilGTEqs[A <: Nat]: Aux[HNil, A, HNil] = new GTs[HNil, A] { type Out = HNil } | |
| implicit def hlistGTEqsLower[A <: Nat, H <: Nat, T <: HList](implicit lts : GTs[T, A], l: A < H): Aux[H :: T, A, H :: lts.Out] = | |
| new GTs[H :: T, A] { type Out = H :: lts.Out } | |
| implicit def hlistGTEqsGreater[A <: Nat, H <: Nat, T <: HList](implicit lts : GTs[T, A], l: H <= A): Aux[H :: T, A, lts.Out] = | |
| new GTs[H :: T, A] { type Out = lts.Out } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t GTs[_1 :: _0 :: _3 :: _2 :: HNil, _2] | |
| GTs.Aux[_1 :: _0 :: _3 :: _2 :: HNil, _2, _3 :: HNil] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait Prepend[P <: HList, S <: HList] { type Out <: HList } | |
| object Prepend { | |
| type Aux[P <: HList, S <: HList, Out0 <: HList] = Prepend[P, S] { type Out = Out0 } | |
| def apply[P <: HList, S <: HList](implicit prepend: Prepend[P, S]): Aux[P, S, prepend.Out] = prepend | |
| implicit def hnilPrepend1[P <: HNil, S <: HList]: Aux[P, S, S] = | |
| new Prepend[P, S] { | |
| type Out = S | |
| } | |
| implicit def hlistPrepend[PH, PT <: HList, S <: HList] | |
| (implicit pt : Prepend[PT, S]): Aux[PH :: PT, S, PH :: pt.Out] = | |
| new Prepend[PH :: PT, S] { | |
| type Out = PH :: pt.Out | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t Prepend[_1 :: _0 :: HNil, _3 :: _2 :: HNil] | |
| Prepend.Aux[_1 :: _0 :: HNil, _3 :: _2 :: HNil, _1 :: _0 :: _3 :: _2 :: HNil] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait Sorted[L <: HList] { | |
| type Out <: HList | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def hnilSorted: Aux[HNil, HNil] = new Sorted[HNil] { type Out = HNil } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | final class Succ[P <: Nat]() extends Nat | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def hlistSorted[H <: Nat, T <: HList, lsOut <: HList, gsOut <: HList, smOut <: HList, slOut <: HList] | |
| (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 | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t Sorted[_1 :: _0 :: _3 :: _2 :: HNil] | |
| Sorted.Aux[_1 :: _0 :: _3 :: _2 :: HNil, _0 :: _1 :: _2 :: _3 :: HNil] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | type _1 = Succ[_0] | |
| type _2 = Succ[_1] | |
| type _3 = Succ[_2] | |
| type _4 = Succ[_3] | |
| type _5 = Succ[_4] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait Sum[A <: Nat, B <: Nat] { type Out <: Nat } | |
| object Sum { | |
| def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]): Aux[A, B, sum.Out] = sum | |
| type Aux[A <: Nat, B <: Nat, C <: Nat] = Sum[A, B] { type Out = C } | |
| implicit def sum1[B <: Nat]: Aux[_0, B, B] = new Sum[_0, B] { type Out = B } | |
| implicit def sum2[A <: Nat, B <: Nat] | |
| (implicit sum : Sum[A, Succ[B]]): Aux[Succ[A], B, sum.Out] = new Sum[Succ[A], B] { type Out = sum.Out } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | trait Sum[A <: Nat, B <: Nat] { type Out <: Nat } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def sum1[B <: Nat]: Aux[_0, B, B] = new Sum[_0, B] { type Out = B } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t Sum[_0, Succ[_0]] | |
| Sum.Aux[_0, Succ[_0], Succ[_0]] // 0 + 1 = 1 | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | implicit def sum2[A <: Nat, B <: Nat] | |
| (implicit sum : Sum[A, Succ[B]]): Aux[Succ[A], B, sum.Out] = new Sum[Succ[A], B] { type Out = sum.Out } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | :t Sum[Succ[Succ[Succ[_0]]], Succ[_0]] | |
| Sum.Aux[Succ[Succ[Succ[_0]]], Succ[_0], Succ[Succ[Succ[Succ[_0]]]]] | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment