Last active
October 21, 2021 14:48
-
-
Save programaker/b9246c4e2e8e40a519986765d2ab316f to your computer and use it in GitHub Desktop.
Revisions
-
programaker revised this gist
Oct 21, 2021 . 1 changed file with 5 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,12 @@ import cats.effect.IO import cats.syntax.foldable._ import cats.syntax.applicative._ import cats.syntax.applicativeError._ import cats.{ApplicativeThrow, Monad} import scala.util.Try // Stores type aliases for effects that have more then one type parameter object Fs { type Either_[A] = Either[Throwable, A] } @@ -66,7 +68,7 @@ val badList = List( def doStuff[F[_]: Monad](value: String, version: Int): F[Int] = { // pretend I'm doing something with the `value` // and returning an updated version (version + 1).pure } def f[F[_]: Monad: ApplicativeThrow](allFrunfles: List[Frunfles], startVersion: Int): F[Int] = { @@ -75,7 +77,7 @@ def f[F[_]: Monad: ApplicativeThrow](allFrunfles: List[Frunfles], startVersion: allFrunfles.foldLeftM(startVersion) { (version, frunfles) => if (frunfles.value.isBlank) { println(">>> <blank>") new IllegalStateException("Frunfles must have a value").raiseError } else { println(s">>> ${frunfles.value}") doStuff(frunfles.value, version) @@ -86,5 +88,4 @@ def f[F[_]: Monad: ApplicativeThrow](allFrunfles: List[Frunfles], startVersion: /// // Change the effect and the list in `f[...]` val out = f[IO](badList, 1).run() -
programaker revised this gist
Oct 5, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ import cats.{ApplicativeThrow, Monad} import scala.util.Try // Stores type aliases for effects that have more than one type parameter object Fs { type Either_[A] = Either[Throwable, A] } -
programaker revised this gist
Sep 29, 2021 . 1 changed file with 49 additions and 26 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,30 +1,45 @@ import cats.effect.IO import cats.syntax.foldable._ import cats.{ApplicativeThrow, Monad} import scala.util.Try // Stores type aliases for effects that have more then one type parameter object Fs { type Either_[A] = Either[Throwable, A] } import Fs._ /// trait Interpreter[F[_]] { def run[A](fa: F[A]): A } object Interpreter { def apply[F[_]](implicit I: Interpreter[F]): Interpreter[F] = I implicit val eitherInterpreter: Interpreter[Either_] = new Interpreter[Either_] { override def run[A](fa: Either_[A]): A = fa match { case Left(e) => throw e case Right(a) => a } } import cats.effect.unsafe.implicits.global implicit val ioInterpreter: Interpreter[IO] = new Interpreter[IO] { override def run[A](fa: IO[A]): A = fa.unsafeRunSync() } implicit val tryInterpreter: Interpreter[Try] = new Interpreter[Try] { override def run[A](fa: Try[A]): A = fa.get } } implicit class InterpreterSyntax[F[_]: Interpreter, A](fa: F[A]) { def run(): A = Interpreter[F].run(fa) } /// final case class Frunfles(value: String) val goodList = List( @@ -46,22 +61,30 @@ val badList = List( Frunfles("Z"), ) /// def doStuff[F[_]: Monad](value: String, version: Int): F[Int] = { // pretend I'm doing something with the `value` // and returning an updated version Monad[F].pure(version + 1) } def f[F[_]: Monad: ApplicativeThrow](allFrunfles: List[Frunfles], startVersion: Int): F[Int] = { // `foldLeftM` works with any `F[_]` as long as a `Monad` instance exists for it! =D // It breaks the folding loop if an error happens - if the Monad instance has some "error" semantic allFrunfles.foldLeftM(startVersion) { (version, frunfles) => if (frunfles.value.isBlank) { println(">>> <blank>") ApplicativeThrow[F].raiseError(new IllegalStateException("Frunfles must have a value")) } else { println(s">>> ${frunfles.value}") doStuff(frunfles.value, version) } } } /// // Change the effect and the list in `f[...]` // Currently available: IO, Either_, Try val out = f[IO](badList, 1).run() -
programaker created this gist
Sep 3, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ import cats.syntax.foldable._ // Modify the commented sections below to change the Effect (as long as the Effect has a Monad) /*type Eff[A] = Either[Throwable, A] object Eff { def success[A](a: A): Eff[A] = Right(a) def error[A](e: Throwable): Eff[A] = Left(e) def run[A](eff: Eff[A]): A = eff.getOrElse(throw _) }*/ /*type Eff[A] = Option[A] object Eff { def success[A](a: A): Eff[A] = Some(a) def error[A](e: Throwable): Eff[A] = None def run[A](eff: Eff[A]): A = eff.get }*/ import cats.effect.IO import cats.effect.unsafe.implicits.global type Eff[A] = IO[A] object Eff { def success[A](a: A): Eff[A] = IO.pure(a) def error[A](e: Throwable): Eff[A] = IO.raiseError(e) def run[A](eff: Eff[A]): A = eff.unsafeRunSync() } final case class Frunfles(value: String) val goodList = List( Frunfles("A"), Frunfles("B"), Frunfles("C"), Frunfles("X"), Frunfles("Y"), Frunfles("Z"), ) val badList = List( Frunfles("A"), Frunfles("B"), Frunfles("C"), Frunfles(""), //<- a bad Frunfles among us! Frunfles("X"), Frunfles("Y"), Frunfles("Z"), ) def doStuff(value: String, version: Int): Eff[Int] = { // pretend I'm doing something with the `value` // and returning an updated version Eff.success(version + 1) } def f(allFrunfles: List[Frunfles], startVersion: Int): Eff[Int] = allFrunfles.foldLeftM(startVersion) { (version, frunfles) => if (frunfles.value.isBlank) { println(">>> <blank>") Eff.error(new IllegalStateException("Frunfles must have a value")) } else { println(s">>> ${frunfles.value}") doStuff(frunfles.value, version) } } val out = Eff.run(f(goodList, 1)) //val out2 = Eff.run(f(badList, 1))