Skip to content

Instantly share code, notes, and snippets.

@lauris
Created May 26, 2014 06:56
Show Gist options
  • Select an option

  • Save lauris/6dd0d55e5b2532e63aae to your computer and use it in GitHub Desktop.

Select an option

Save lauris/6dd0d55e5b2532e63aae to your computer and use it in GitHub Desktop.
Monoidal FizzBuzz In Scala by Dominic Fox
import scalaz._
object Main {
case class FizzBuzz(elems: String*)
implicit object FizzBuzzMonoid extends Monoid[FizzBuzz] {
override def zero = FizzBuzz()
override def append(f1: FizzBuzz, f2: => FizzBuzz): FizzBuzz = FizzBuzz(f1.elems ++ f2.elems :_*)
}
implicit object FuzzBuzzShow extends Show[FizzBuzz] {
override def shows(f1: FizzBuzz): String = f1.elems.mkString("")
}
def interpreter(name: String, cond: Int => Boolean): Int => FizzBuzz = i =>
if (cond(i)) FizzBuzz(name) else FizzBuzzMonoid.zero
val fizz = interpreter("fizz", (i: Int) => (i % 3) == 0)
val buzz = interpreter("buzz", (i: Int) => (i % 5) == 0)
def fizzBuzzer[T](interpreters: (Int => T)*)(implicit m: Monoid[T], s: Show[T]): Int => String = i => {
val interpreted: T = interpreters.map(_.apply(i)).fold(m.zero)(m.append(_, _))
if (interpreted == m.zero) i.toString else s.shows(interpreted)
}
def main(args: Array[String]) {
(1 to 100).map(fizzBuzzer(fizz, buzz)).foreach(println)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment