Skip to content

Instantly share code, notes, and snippets.

@pandaforme
Created February 20, 2017 08:10
Show Gist options
  • Save pandaforme/2b913d5fedde6861e30b39fe476873ce to your computer and use it in GitHub Desktop.
Save pandaforme/2b913d5fedde6861e30b39fe476873ce to your computer and use it in GitHub Desktop.
Free your context
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import cats.implicits._
import simulacrum.typeclass
sealed trait Error
case class SomethingWrong(e: Throwable) extends Error
@typeclass
trait Capture[F[_]] {
def capture[A](a: => A): F[A]
}
object Capture {
implicit def futureCapture(implicit ec: ExecutionContext) = new Capture[Future] {
override def capture[A](a: => A): Future[A] = Future(a)(ec)
}
implicit val tryCapture = new Capture[Try] {
override def capture[A](a: => A): Try[A] = Try(a)
}
implicit val optionCapture = new Capture[Option] {
override def capture[A](a: => A): Option[A] = Option(a)
}
implicit val eitherCapture = new Capture[Either[Error, ?]] {
override def capture[A](a: => A): Either[Error, A] = {
val fatal: Either[Throwable, A] = Either.catchNonFatal(a)
val either: Either[Error, A] = fatal.leftMap(SomethingWrong(_))
either
}
}
implicit def fgCapture[F[_]: Capture, G[_]: Capture] = new Capture[λ[α => F[G[α]]]] {
override def capture[A](a: => A): F[G[A]] = {
implicitly[Capture[F]].capture(implicitly[Capture[G]].capture(a))
}
}
}
object Main extends App {
import scala.concurrent.ExecutionContext.Implicits.global
import Capture._
def getUser[F[_]: Capture](id: String): F[String] = {
Capture[F].capture(s"Get a user id: ${id}")
}
private val user1: Try[String] = getUser[Try]("123")
private val user2: Option[String] = getUser[Option]("123")
private val user3: Either[Error, String] = getUser[Either[Error, ?]]("123")
private val user4: Future[String] = getUser[Future]("123")
private val user5: Future[Try[String]] = getUser[λ[α => Future[Try[α]]]]("123")
private val user6: Future[Option[String]] = getUser[λ[α => Future[Option[α]]]]("123")
private val user7: Future[Either[Error, String]] = getUser[λ[α => Future[Either[Error, α]]]]("123")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment