Skip to content

Instantly share code, notes, and snippets.

@einblicker
Created October 30, 2011 10:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save einblicker/1325753 to your computer and use it in GitHub Desktop.
Save einblicker/1325753 to your computer and use it in GitHub Desktop.
type-level FizzBuzz
trait Nat {
type IsZero <: Bool
type Prev <: Nat
type Divisable[A <: Nat] = DivisableImpl[A, A]
type DivisableImpl[A <: Nat, B <: Nat] <: Bool
}
trait Z extends Nat {
type IsZero = True
type Prev = Nothing
type DivisableImpl[A <: Nat, B <: Nat] = B#IsZero
}
trait S[N <: Nat] extends Nat {
type IsZero = False
type Prev = N
type DivisableImpl[A <: Nat, B <: Nat] = B#IsZero#If[Bool, N#DivisableImpl[A, A#Prev], N#DivisableImpl[A, B#Prev]]
}
trait FizzBuzzBase extends Nat {
type IsZero = Nothing
type Prev = Nothing
type DivisableImpl[A <: Nat, B <: Nat] = Nothing
}
trait Fizz extends FizzBuzzBase
trait Buzz extends FizzBuzzBase
trait FizzBuzz extends FizzBuzzBase
type _0 = Z
type _1 = S[_0]
type _2 = S[_1]
type _3 = S[_2]
type _4 = S[_3]
type _5 = S[_4]
type _6 = S[_5]
type _7 = S[_6]
type _8 = S[_7]
type _9 = S[_8]
type _10 = S[_9]
type _11 = S[_10]
type _12 = S[_11]
type _13 = S[_12]
type _14 = S[_13]
type _15 = S[_14]
trait Bool {
type If[Ty, T <: Ty, F <: Ty] <: Ty
}
trait True extends Bool {
type If[Ty, T <: Ty, F <: Ty] = T
}
trait False extends Bool {
type If[Ty, T <: Ty, F <: Ty] = F
}
trait Fun {
type Apply[A <: Nat] <: Nat
}
trait List {
type Map[F <: Fun] <: List
}
trait Nil extends List {
type Map[F <: Fun] = Nil
}
trait ::[A <: Nat, L <: List] extends List {
type Map[F <: Fun] = ::[F#Apply[A], L#Map[F]]
}
type NumList = _1 :: _2 :: _3 :: _4 :: _5 :: _6 :: _7 :: _8 :: _9 :: _10 :: Nil
type FizzBuzzList = _1 :: _2 :: Fizz :: _4 :: Buzz :: Fizz :: _7 :: _8 :: Fizz :: Buzz :: Nil
println(implicitly[
NumList#Map[
Fun {
type Apply[A <: Nat] = A#Divisable[_15]#If[Nat, FizzBuzz, A#Divisable[_3]#If[Nat, Fizz, A#Divisable[_5]#If[Nat, Buzz, A]]]
}
] =:= FizzBuzzList])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment