Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created March 5, 2022 08:49
Show Gist options
  • Save xuwei-k/913e545426697ee2963335976129f1c7 to your computer and use it in GitHub Desktop.
Save xuwei-k/913e545426697ee2963335976129f1c7 to your computer and use it in GitHub Desktop.
scalaVersion := "3.1.2-RC1"
import scala.compiletime.ops.string.{+, Substring, Length}
import scala.compiletime.ops.int.{<, >}
import scala.compiletime.ops.int
sealed trait HList {
def ::[T](t: T): T :: this.type = new ::(t, this)
}
final case class ::[H, +T <: HList](h: H, t: T) extends HList
sealed trait HNil extends HList
@annotation.experimental
object TypeLevelSortString {
type LTs[A <: HList, B <: Int] <: HList = A match
case HNil =>
HNil
case t :: ts =>
(t < B) match
case true =>
t :: LTs[ts, B]
case false =>
LTs[ts, B]
type GTs[A <: HList, B <: Int] <: HList = A match
case HNil =>
HNil
case t :: ts =>
(t > B) match
case true =>
t :: GTs[ts, B]
case false =>
GTs[ts, B]
type HListConcat[A <: HList, B <: HList] <: HList = A match
case HNil =>
B
case h :: t =>
h :: (HListConcat[t, B])
type SortStr[A <: String] <: String =
A match
case _ =>
HListToString[Sort[MapHList[StringToHList[A], ToInt]]]
type Sort[A <: HList] <: HList = A match
case HNil =>
HNil
case h :: t =>
HListConcat[Sort[LTs[t, h]], h :: Sort[GTs[t, h]]]
type ReverseHList[A <: HList] <: HList =
A match
case _ =>
ReverseHList0[HNil, A]
type ReverseHList0[Acc <: HList, Src <: HList] <: HList =
Src match
case HNil =>
Acc
case x :: xs =>
ReverseHList0[x :: Acc, xs]
type ReverseStr[A <: String] <: String =
A match
case _ =>
ReverseStr0["", A]
type ReverseStr0[Acc <: String, Src <: String] <: String =
Length[Src] match
case 0 =>
Acc
case _ =>
ReverseStr0[Substring[Src, 0, 1] + Acc, Substring[Src, 1, Length[Src]]]
type HListToString[A <: HList] <: String =
A match
case _ =>
HListToString0[A, ""]
type HListToString0[A <: HList, Acc <: String] <: String =
A match
case HNil =>
Acc
case x :: xs =>
HListToString0[xs, Acc + int.ToString[x]]
type StringToHList[A <: String] <: HList =
A match {
case _ =>
StringToHList0[HNil, ReverseStr[A]]
}
type StringToHList0[+Acc <: HList, Src <: String] <: HList =
Length[Src] match
case 0 =>
Acc
case _ =>
StringToHList0[
Substring[Src, 0, 1] :: Acc,
Substring[Src, 1, Length[Src]]
]
summon[ReverseStr["abc"] =:= "cba"]
summon[StringToHList["123"] =:= ("1" :: "2" :: "3" :: HNil)]
summon[
ReverseHList[
1 :: 2 :: 3 :: 4 :: HNil
] =:= (
4 :: 3 :: 2 :: 1 :: HNil
)
]
summon[
Sort[
5 :: 3 :: 7 :: 2 :: 1 :: 6 :: 4 :: HNil
] =:= (
1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: HNil
)
]
summon[
SortStr["8537029164"] =:= "0123456789"
]
type MapHList[A <: HList, F[_]] <: HList = A match
case h :: t => F[h] :: MapHList[t, F]
case HNil => HNil
type ToInt[A <: String] <: Int = A match
case "0" => 0
case "1" => 1
case "2" => 2
case "3" => 3
case "4" => 4
case "5" => 5
case "6" => 6
case "7" => 7
case "8" => 8
case "9" => 9
summon[StringToHList["abc"] =:= ("a" :: "b" :: "c" :: HNil)]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment