Created
March 14, 2022 11:45
-
-
Save zckkte/40f01436a8f2bd58e0905f0e09ba4421 to your computer and use it in GitHub Desktop.
Toy functional effect system
This file contains 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 characters
object Console { | |
def putStrLn(str: => String) = TIO.effect(println(str)) | |
} |
This file contains 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 characters
object FailAndRecover extends TIOApp { | |
def run = { | |
(for { | |
_ <- putStrLn("running first effect") | |
_ <- TIO.fail(new RuntimeException) | |
_ <- putStrLn("second effect - will not run") | |
} yield ()).recover { | |
case NonFatal(e) => | |
putStrLn(s"recovered from failure: ${e.getClass.getName}") | |
} | |
} | |
} |
This file contains 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 characters
import scala.util._ | |
trait Runtime { | |
def unsafeRunSync[A](tio: TIO[A]): Try[A] | |
} | |
object Runtime extends Runtime { | |
def unsafeRunSync[A](tio: TIO[A]): Try[A] = eval(tio) | |
private def eval[A](tio: TIO[A]): Try[A] = { | |
tio match { | |
case TIO.Effect(a) => | |
Try(a()) | |
case TIO.FlatMap(tio, f: (Any => TIO[Any])) => | |
eval[Any](tio) match { | |
case Success(res) => eval(f(res)) | |
case Failure(e) => Failure(e) | |
} | |
case TIO.Fail(t) => | |
Failure(t) | |
case TIO.Recover(tio, f) => | |
eval(tio) match { | |
case Failure(e) => eval(f(e)) | |
case success => success | |
} | |
} | |
} | |
} |
This file contains 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 characters
package example | |
sealed trait TIO[+A] { | |
def flatMap[B](f: A => TIO[B]): TIO[B] = TIO.FlatMap(this, f) | |
def map[B](f: A => B): TIO[B] = flatMap(a => TIO.succeed(f(a))) | |
def recover[B >: A](f: Throwable => TIO[B]): TIO[B] = TIO.Recover(this, f) | |
def *>[B](that: TIO[B]): TIO[B] = flatMap(_ => that) | |
} | |
object TIO { | |
case class Effect[+A](a: () => A) extends TIO[A] | |
case class FlatMap[A, B](tio: TIO[A], f: A => TIO[B]) extends TIO[B] | |
case class Fail[A](e: Throwable) extends TIO[A] | |
case class Recover[A](tio: TIO[A], f: Throwable => TIO[A]) extends TIO[A] | |
def succeed[A](a: A): TIO[A] = Effect(() => a) | |
def effect[A](a: => A): TIO[A] = Effect(() => a) | |
def fail[A](throwable: Throwable): TIO[A] = Fail(throwable) | |
} |
This file contains 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 characters
trait TIOApp { | |
def run: TIO[Any] | |
final def main(args: Array[String]): Unit = Runtime.unsafeRunSync(run).get | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment