Skip to content

Instantly share code, notes, and snippets.

@Tvaroh
Last active June 1, 2020 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tvaroh/8263f00f421dc51238bb0c181a6f6b1b to your computer and use it in GitHub Desktop.
Save Tvaroh/8263f00f421dc51238bb0c181a6f6b1b to your computer and use it in GitHub Desktop.
import cats.implicits._
import cats.Applicative
import tofu.syntax.handle._
import tofu.syntax.raise._
import tofu.{Handle, Raise}
sealed trait Restorable[A]
object Restorable {
def pure[A](a: A): Restorable[A] =
Pure(a)
def success[F[_], A](a: A)(implicit F: Applicative[F]): F[Restorable[A]] =
F.pure(pure(a))
def failure[F[_], A](a: A)(implicit raise: Raise[F, Failed[A]]): F[Restorable[A]] =
Failed(a).raise[F, Restorable[A]]
def restore[F[_], A](restorable: F[Restorable[A]])
(implicit F: Applicative[F],
handle: Handle[F, Failed[A]]): F[A] =
restorable.attempt.map { _
.fold(
_.a,
{
case Pure(a) => a
case Failed(a) => a
}
)
}
implicit class RestorableOps[F[_], A](val restorable: F[Restorable[A]]) extends AnyVal {
def restore(implicit F: Applicative[F],
handle: Handle[F, Failed[A]]): F[A] =
Restorable.restore(restorable)
}
private case class Pure[A](a: A)
extends Restorable[A]
private case class Failed[A](a: A)
extends RuntimeException
with Restorable[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment