Skip to content

Instantly share code, notes, and snippets.

@joshuakfarrar
Last active December 14, 2018 18:57
Show Gist options
  • Select an option

  • Save joshuakfarrar/736d8b65150b07bd565be234b2c3d696 to your computer and use it in GitHub Desktop.

Select an option

Save joshuakfarrar/736d8b65150b07bd565be234b2c3d696 to your computer and use it in GitHub Desktop.
cats.effect._, HKTs, Kleisli, for comprehensions, and `implicit F: Monad[F]`; ADT promotion and more!
package me.omega
import cats.effect.{IOApp, IO, ExitCode}
import cats.Monad
import cats.data.Kleisli
import cats.syntax.all._
object Main extends IOApp {
override def run(args: List[String]): IO[ExitCode] = new App[IO].run.as(ExitCode.success) // `.as` is sugar for `.map[A](a: A)(_ => a)`
}
class App[F[_]](implicit F: Monad[F]) { // needed so that things of F[_] are flatMappable, so we can for-comp as in run()
case class Thing(name: String)
case class PromotedThing(name: String, exists: Boolean)
// Kleislis compose easily; IO[String => Thing] and IO[String => PromotedThing] don't immediately.
def run: F[Unit] = for {
thingA <- createThing("foo").map(promoteThing(_)) // this will be Kleisli[IO, String, PromotedThing]
thingB <- createThing("bar") // and this is Kleisli[IO, String, Thing]
} yield doSomething(thingA, thingB) // pure function which operates on PromotedThing and Thing
val createThing: Kleisli[F, String, Thing] =
Kleisli((name: String) => F.pure(Thing(name))) // accept name: String and lift a new Thing into F[Thing]
def promoteThing(thing: Thing): PromotedThing = PromotedThing(thing.name, true) // promote Thing to PromotedThing
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment