-
-
Save sidnt/646aa3cf5c34892a0f7cce4f7ccb8742 to your computer and use it in GitHub Desktop.
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 lzio | |
import zio._ | |
import console._ | |
object helpers { | |
type ??? = Nothing | |
case class User(name: String, age: Int) | |
val u1 = User("Martin", 42) | |
type Year = Short | |
case class Country(name: String, capital: String, foundedIn: Year) | |
val c1 = Country("Switzerland", "Bern", 1848) | |
def makeMessage(i: Int): String = "the int> " + i | |
def makeMessage(u: User): String = s"hello ${u.name} | your age is ${u.age}" | |
def makeMessage(u: User, c:Country): String = | |
s"found user: ${u.name} | found country: ${c.name}" | |
}; import helpers._ | |
object demo1 extends App { | |
/** wazp that depends on type R | |
* and returns it back as is | |
* . declare the types | |
* . provide the implementation | |
* . run it | |
*/ | |
type R = Int | |
lazy val z1: ZIO[Int, Nothing, Int] = for { | |
e <- ZIO.environment[Int] | |
} yield e | |
val z1b: ZIO[Any, Nothing, Int] = z1.provide(88) | |
val printEnvironment = for { | |
i <- z1b | |
_ <- putStrLn("got in from the environment: " + i) | |
} yield () | |
lazy val z1p: URIO[Console, ExitCode] = printEnvironment.exitCode | |
// def run(args: List[String]) = z1p | |
/** wazp that depends on type R | |
* and projects a value of type A | |
* from that type R | |
* using the given projection function | |
* . types, then | |
* . implementation | |
* . run | |
*/ | |
type A = String | |
def projectionFunction(r:Int): String = s"projecting Int to String: " + r.toString() | |
lazy val z2: ZIO[Int, Nothing, String] = | |
for { | |
s <- ZIO.access[Int](i => projectionFunction(i)) | |
} yield s | |
val z2p:ZIO[Any, Nothing, String] = z2.provide(77) | |
val z2b: ZIO[Console, Nothing, Unit] = for { | |
s <- z2p | |
_ <- putStrLn(s) | |
} yield () | |
// lazy val z2p: UIO[ExitCode] = ??? | |
def run(args: List[String]) = z2b.exitCode | |
} | |
object demo2 extends App { | |
/** wazp that depends on type User | |
* but does nothing with it, just exit simply | |
*/ | |
lazy val z1: ZIO[User with Console, Nothing, ExitCode] = | |
for { | |
_ <- ZIO.access[User](identity) | |
ec <- putStrLn("bye bye").exitCode | |
} yield ec | |
// val z2 = z1.provide(u1) | |
// lazy val z1p: UIO[ExitCode] = z1.provideSome(u1) | |
// def run(args: List[String]) = z1p | |
/** wazp that depends on User type in R | |
* and creates a message out of it | |
* and prints it out to the console | |
*/ | |
lazy val z2: ZIO[User, Nothing, String] = | |
for { | |
u <- ZIO.access[User](identity) | |
m = makeMessage(u) | |
} yield m | |
val z2b = z2.provide(u1) | |
val z2c: ZIO[Console, Nothing, Unit] = for { | |
m <- z2b | |
_ <- putStrLn(m) | |
} yield () | |
val z2d:ZIO[Console, Nothing, ExitCode] = z2c.exitCode | |
// lazy val z2p: UIO[ExitCode] = ??? | |
def run(args: List[String]) = z2d | |
} | |
object demo3 extends App { | |
/** wazp that depends on type User & Country | |
* generates the message from provided function | |
* prints it to the console | |
*/ | |
lazy val z1: ZIO[User with Country, Nothing, String] = | |
for { | |
u <- ZIO.access[User](identity) | |
c <- ZIO.access[Country](identity) | |
m = makeMessage(u,c) | |
} yield m | |
val uwc: User with Country = ??? | |
val z2 = z1.provide(uwc) | |
val z2b: ZIO[User with Country with Console, Nothing, Unit] = | |
for { | |
m <- z1 | |
_ <- putStrLn(m) | |
} yield () | |
val z3 = z2 | |
val uwc2: User with Country with Console = ??? | |
lazy val z1p: UIO[ExitCode] = ??? | |
def run(args: List[String]) = z1p | |
} | |
object demo4 extends App { | |
/** create a Has[User] | |
*/ | |
lazy val hu1: Has[User] = Has(u1) | |
/** extract a user from a Has[User] | |
*/ | |
lazy val u1Fhu1: User = hu1.get | |
/** create a Has[Country] | |
*/ | |
lazy val hc1: Has[Country] = Has(c1) | |
/** extract a country from a Has[Country] | |
*/ | |
lazy val c1Fhc1: Country = hc1.get | |
/** wazp that depends on Has[User] with Has[Country] | |
* provide the appropriate environment | |
* make the message | |
* and then print it | |
*/ | |
lazy val z1: ZIO[Has[User] with Has[Country], Nothing, String] = | |
for { | |
u <- ZIO.access[Has[User]](_.get) | |
c <- ZIO.access[Has[Country]](_.get) | |
m = makeMessage(u,c) | |
} yield m | |
val z1b = z1.provide(hu1 ++ hc1) | |
val z1c = for { | |
m <- z1b | |
_ <- putStrLn(m) | |
} yield () | |
// lazy val z1p: UIO[ExitCode] = ??? | |
def run(args: List[String]) = z1c.exitCode | |
} | |
object demo5 { | |
/** a country service injected into | |
* a user service | |
* to provide messages like above | |
* demonstrate the wiring | |
*/ | |
object country { | |
type Country = Has[country.Service] | |
trait Service { | |
val name: String | |
val capital: String | |
val foundedIn: Year | |
} | |
val switzerland: ZLayer[Any, Nothing, Country] = | |
ZLayer.succeed(new country.Service { | |
val name: String = "Switzerland" | |
val capital: String = "Bern" | |
val foundedIn: helpers.Year = 1894 | |
}) | |
} | |
object user { | |
type User = Has[user.Service] | |
trait Service { | |
val name: String | |
val age: Int | |
} | |
val chet: ZLayer[Any, Nothing, User] = | |
ZLayer.succeed(new user.Service { | |
val name: String = "Chet" | |
val age: Int = 24 | |
}) | |
} | |
object message { | |
type Message = Has[message.Service] | |
trait Service { | |
val message: String | |
} | |
val m1: ZLayer[User with Country, Nothing, Message] = | |
ZLayer.fromFunction[user.User with country.Country, message.Service]( uwc => new message.Service { | |
val message: String = makeMessage(uwc.get[User], uwc.get[Country]) | |
}) | |
} | |
/** swapping layers | |
* | |
*/ | |
/** very specialized type of layer | |
* usually a layer which is quite optional | |
* for testing | |
* we have a test layer / test harness layer | |
* we're using the same api as live layers | |
* as all have got the same interface | |
* but the test implementation is different from live implementation | |
* . | |
* logging | |
* we might want to have logs of everything, eg | |
* user events / network events / events->proposals->action | |
* action being accepted by the | |
* .... | |
* aspect takes a network layer | |
* returns a network layer with logging | |
* the incoming/outcoming api is the same | |
* but it has done | |
* it has modified teh network layer | |
* to add logging to it | |
* . | |
* they are special layer | |
* where it takes an existing layer | |
* and it modifies it | |
* | |
*/ | |
val _ = null | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment