Last active
December 23, 2021 06:27
-
-
Save iamanandkris/0078da0d619fc7cef9dd9a9c1c883298 to your computer and use it in GitHub Desktop.
Attempt to use State monad within ZIO
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 characters
import cats.data.State | |
import scalaz.zio.{DefaultRuntime, Task, ZIO} | |
type UserID = String | |
case class UserProfile(name:String) | |
trait Database[F[_]] { | |
def lookup(id: UserID): Task[F[UserProfile]] | |
def update(id: UserID, profile: UserProfile): Task[F[Unit]] | |
} | |
trait Logger[F[_]] { | |
def info(id: String): Task[F[Unit]] | |
} | |
trait Operation | |
trait DatabaseOperation extends Operation | |
case class UserUpdated(id:UserID, profile:UserProfile) extends DatabaseOperation | |
case class UserLookedUp(id:UserID) extends DatabaseOperation | |
trait LoggerOperation extends Operation | |
case class MessageLogged(message:String) extends LoggerOperation | |
type TestState[A] = cats.data.State[List[Operation], A] | |
trait TestDatabaseService extends Database[TestState] { | |
private var map: Map[UserID, UserProfile] = Map("abc" -> UserProfile("testName")) | |
def lookup(id: UserID): Task[TestState[UserProfile]] = | |
Task(for{ | |
_ <- State.modify[List[Operation]](s => UserLookedUp(id) :: s) | |
s <- State.inspect[List[Operation], UserProfile](s => map(id)) | |
}yield s) | |
def update(id: UserID, profile: UserProfile): Task[TestState[Unit]] = | |
Task.effect {for{ | |
_ <- State.modify[List[Operation]](s => UserUpdated(id, profile) :: s) | |
s <- State.inspect[List[Operation], Unit](s => map = map + (id -> profile) ) | |
}yield s} | |
} | |
trait TestLoggerService extends Logger[TestState] { | |
def info(id: String): Task[TestState[Unit]] = | |
Task(for{ | |
s <- State.modify[List[Operation]](s => MessageLogged(id) :: s) | |
_ <- State.inspect[List[Operation], Unit](s => ()) | |
}yield s) | |
} | |
object FinalEnv extends TestLoggerService with TestDatabaseService | |
val lookedupProfile: ZIO[Database[TestState] with Logger[TestState], Throwable, TestState[UserProfile]] = | |
for { | |
profile <- ZIO.accessM[Database[TestState]](x => x.lookup("abc")) | |
x <- ZIO.access[Logger[TestState]](x => profile.map(xs => x.info(xs.name))) | |
} yield profile | |
val runtime = new DefaultRuntime {} | |
runtime.unsafeRun(lookedupProfile.provide(FinalEnv)).run(Nil).value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment