Skip to content

Instantly share code, notes, and snippets.

@tixxit
Created November 14, 2012 16:04
Show Gist options
  • Save tixxit/4072983 to your computer and use it in GitHub Desktop.
Save tixxit/4072983 to your computer and use it in GitHub Desktop.
Compile time FizzBuzz in Scala.
package net.tixxit
import shapeless._
import Nat._
final class Fizz
final class Buzz
trait FizzBuzzAux[A <: Nat, B <: HList] {
def apply(): List[String]
}
trait FizzBuzzAux0 {
implicit def fizzBuzz1[A <: Nat, B <: HList](implicit prev: FizzBuzzAux[A, B], toInt: ToInt[Succ[A]]) = {
new FizzBuzzAux[Succ[A], Succ[A] :: B] { def apply = toInt().toString :: prev() }
}
}
trait FizzBuzzAux1 extends FizzBuzzAux0 {
implicit def fizzBuzz2[A <: Nat, B <: HList](implicit prev: FizzBuzzAux[A, B], mod: ModAux[Succ[A], _3, _0]) = {
new FizzBuzzAux[Succ[A], Fizz :: B] { def apply = "Fizz" :: prev() }
}
implicit def fizzBuzz3[A <: Nat, B <: HList](implicit prev: FizzBuzzAux[A, B], mod: ModAux[Succ[A], _5, _0]) = {
new FizzBuzzAux[Succ[A], Buzz :: B] { def apply = "Buzz" :: prev() }
}
}
object FizzBuzzAux extends FizzBuzzAux1 {
implicit def fizzBuzz0 = new FizzBuzzAux[_1, _1 :: HNil] { def apply() = "1" :: Nil }
implicit def fizzBuzz4[A <: Nat, B <: HList](implicit prev: FizzBuzzAux[A, B], mod1: ModAux[Succ[A], _3, _0], mod2: ModAux[Succ[A], _5, _0]) = {
new FizzBuzzAux[Succ[A], (Fizz, Buzz) :: B] { def apply = "FizzBuzz" :: prev() }
}
}
trait FizzBuzz[A <: Nat, B <: Nat]
object FizzBuzz {
implicit def fizzBuzz[A <: Nat, B <: Nat, C <: Nat, H <: HList](implicit prod: ProdAux[A, B, C], aux: FizzBuzzAux[C, H]) = {
new FizzBuzz[A, B] { override def toString = aux().reverse mkString "\n" }
}
}
object Main extends App {
println(implicitly[FizzBuzz[_10, _10]])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment