Skip to content

Instantly share code, notes, and snippets.

@s5bug
Last active June 7, 2020 19:59
Show Gist options
  • Save s5bug/f9c6874b33139c1b0f9bfa1d7d673cd6 to your computer and use it in GitHub Desktop.
Save s5bug/f9c6874b33139c1b0f9bfa1d7d673cd6 to your computer and use it in GitHub Desktop.
Scala "Enterprize" Fizzbuzz
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.numeric._
import fs2._
def defaultMap[T](implicit numeric: Numeric[T]): Map[T Refined Positive, String] =
Map(
refineV[Positive](numeric.fromInt(3)).right.get -> "fizz",
refineV[Positive](numeric.fromInt(5)).right.get -> "buzz"
)
def fizzbuzz[F[_], T](
map: Map[T Refined Positive, String]
)(implicit intg: Integral[T]): Pipe[F, T Refined Positive, String] =
in =>
for {
i <- in
r = i.value
d = map.keys.filter(n => intg.rem(r, n.value) == intg.zero).map(map)
} yield if(d.isEmpty) r.toString else d.foldLeft("")(_ ++ _)
import cats._
import cats.effect._
import cats.implicits._
import eu.timepit.refined._
import eu.timepit.refined.api._
import eu.timepit.refined.auto._
import eu.timepit.refined.numeric._
import fs2._
import scala.collection.immutable.NumericRange
def numStream[F[_], T](start: T, end: T, by: T)(implicit intg: Integral[T]): Stream[F, T] =
Stream.emits(NumericRange(start, end, by))
def hardRefine[F[_], T, R](s: Stream[F, T])(implicit v: Validate[T, R]): Stream[F, T Refined R] =
s.map(refineV[R](_).right.get)
def passThroughFizzbuzz[F[_], T: Integral](
s: Stream[F, T Refined Positive],
map: Map[T Refined Positive, String]
): Stream[F, String] = s.through(fizzbuzz(map))
def printAll[F[_], T: Show](s: Stream[F, T])(implicit sync: Sync[F]): Stream[F, Unit] =
s.evalMap(e => sync.delay(println(s"$e")))
def program[F[_]: Sync, T: Show](implicit intg: Integral[T]): Stream[F, Unit] = {
val nums = numStream[F, T](intg.fromInt(1), intg.fromInt(100), intg.fromInt(1))
val ref = hardRefine[F, T, Positive](nums)
val fb = passThroughFizzbuzz[F, T](ref, defaultMap)
val pr = printAll[F, String](fb)
pr
}
program[IO, Int].run.unsafeRunSync()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment