Skip to content

Instantly share code, notes, and snippets.

@olafurpg
Created January 1, 2020 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save olafurpg/46667949e460fecc77f95548c06e1c0c to your computer and use it in GitHub Desktop.
Save olafurpg/46667949e460fecc77f95548c06e1c0c to your computer and use it in GitHub Desktop.
package minimize
object app {
import cats.tagless._
import util.Try
import cats.tagless.implicits._
import cats.implicits._
import cats._
import cats.free.Free
import cats.arrow.FunctionK
@finalAlg
@autoFunctorK
@autoSemigroupalK
@autoProductNK
trait ExpressionAlg[F[_]] {
def num(i: String): F[Float]
def divide(dividend: Float, divisor: Float): F[Float]
}
import ExpressionAlg.autoDerive._
@finalAlg @autoFunctorK
trait Increment[F[_]] {
def plusOne(i: Int): F[Int]
}
import Increment.autoDerive._
implicit object incTry extends Increment[Try] {
def plusOne(i: Int) = Try(i + 1)
}
def program[F[_]: Monad: Increment](i: Int): F[Int] = for {
j <- Increment[F].plusOne(i)
z <- if (j < 10000) program[F](j) else Monad[F].pure(j)
} yield z
implicit def toFree[F[_]]: F ~> Free[F, *] = λ[F ~> Free[F, *]](t => Free.liftF(t))
program[Free[Try, *]](0).foldMap(FunctionK.id)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment