Skip to content

Instantly share code, notes, and snippets.

@PiotrJander
Created July 5, 2019 21:31
Show Gist options
  • Save PiotrJander/ed1abbffb59a94a582fdf70b57463c0b to your computer and use it in GitHub Desktop.
Save PiotrJander/ed1abbffb59a94a582fdf70b57463c0b to your computer and use it in GitHub Desktop.
import zio.{DefaultRuntime, Task, ZIO}
import scala.io.StdIn
object Example extends App {
object Console {
trait Service {
def getStrLn(): Task[String]
def putStrLn(s: String): Task[Unit]
}
}
trait Console {
def console: Console.Service
}
object cs {
def getStrLn(): ZIO[Console, Throwable, String] =
ZIO.accessM(_.console.getStrLn())
def putStrLn(s: String): ZIO[Console, Throwable, Unit] =
ZIO.accessM(_.console.putStrLn(s))
}
trait ConsoleLive extends Console {
def console: Console.Service =
new Console.Service {
def getStrLn(): Task[String] = ZIO.effect(StdIn.readLine())
def putStrLn(s: String): Task[Unit] = ZIO.effectTotal(println(s))
}
}
object ConsoleLive extends ConsoleLive
class TestService extends Console.Service {
private var stdin: List[String] = List()
private var stdout: List[String] = List()
def setStdIn(s: List[String]): Task[Unit] =
ZIO.effectTotal { stdin = s }
def getStdOut: Task[List[String]] =
ZIO.effect(stdout)
def getStrLn(): Task[String] =
for {
res <- Task(stdin)
x :: xs = res
_ <- ZIO.effectTotal { stdin = xs }
} yield x
def putStrLn(s: String): Task[Unit] =
ZIO.effectTotal { stdout = s :: stdout }
}
trait TestConsole extends Console {
val console: TestService = new TestService
}
object TestConsole extends TestConsole
def code: ZIO[Console, Throwable, Unit] =
for {
name <- cs.getStrLn()
_ <- cs.putStrLn(name)
} yield ()
def code1: ZIO[Any, Throwable, Unit] =
code.provide(ConsoleLive)
def code2: ZIO[Any, Throwable, Unit] =
code.provide(TestConsole)
def run(args: List[String]) = {
val runtime = new DefaultRuntime {}
runtime.unsafeRun(code1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment