Last active
May 31, 2021 08:38
-
-
Save programaker/51c31e8c1ca3d4715b872d610c1a636c to your computer and use it in GitHub Desktop.
Revisions
-
programaker revised this gist
May 31, 2021 . 1 changed file with 30 additions and 21 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,12 +1,16 @@ import cats.Monad import cats.syntax.functor.* import cats.effect.IO import cats.effect.unsafe.implicits.global case class Frunfles(id: Long, name: String) trait DatabaseConnection: def exec[F[_]: Monad](op: String): F[Unit] object DatabaseConnection: given DatabaseConnection with def exec[F[_]: Monad](op: String): F[Unit] = Monad[F].pure(println(s">>> DB op = $op")) // single-dependency "primitive" environments type MonadEnv[F[_], A] = Monad[F] ?=> F[A] @@ -22,30 +26,35 @@ type Env2[F[_], A] = DatabaseEnv[MonadEnv[F, A]] type Env3[F[_], A] = (DatabaseConnection, Monad[F]) ?=> F[A] type Env4[F[_], A] = (Monad[F], DatabaseConnection) ?=> F[A] // need "Env" def findAllFrunfles[F[_]]: Env[F, List[Frunfles]] = summon[DatabaseConnection].exec("findAll").map(_ => List.empty) def findFrunflesById[F[_]](id: Long): Env[F, Option[Frunfles]] = summon[DatabaseConnection].exec("findById").map(_ => None) // need "Env2" def insertFrunfles[F[_]](f: Frunfles): Env2[F, Unit] = summon[DatabaseConnection].exec("insert") // need "Env3" def updateFrunfles[F[_]](f: Frunfles): Env3[F, Unit] = summon[DatabaseConnection].exec("update") // need "Env4" def deleteFrunfles[F[_]](id: Long): Env4[F, Unit] = summon[DatabaseConnection].exec("delete") // nesting order does not matter! // parameter order does not matter! // mixing different envs does not matter! // the functions are called as if the envs don't exist at all! val io: IO[Unit] = for _ <- insertFrunfles[IO](Frunfles(1L, "frunfles")) _ <- findFrunflesById[IO](1L) _ <- updateFrunfles[IO](Frunfles(1L, "sbrubbles")) _ <- deleteFrunfles[IO](1L) yield () val res1 = io.unsafeRunSync() val res2 = findAllFrunfles[IO].unsafeRunSync() -
programaker revised this gist
May 28, 2021 . 1 changed file with 1 addition and 0 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 @@ -39,6 +39,7 @@ def deleteFrunfles[F[_]](id: Long): Env4[F, Unit] = Monad[F].pure(()) // nesting order does not matter! // parameter order does not matter! // mixing different envs does not matter! // the functions are called as if the envs don't exist at all! val res: IO[Unit] = for _ <- insertFrunfles[IO](Frunfles(1L, "frunfles")) -
programaker revised this gist
May 28, 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 @@ -13,7 +13,7 @@ type MonadEnv[F[_], A] = Monad[F] ?=> F[A] type DatabaseEnv[A] = DatabaseConnection ?=> A // composing envs by nesting // both are equivalent! type Env[F[_], A] = MonadEnv[F, DatabaseEnv[A]] type Env2[F[_], A] = DatabaseEnv[MonadEnv[F, A]] -
programaker revised this gist
May 28, 2021 . 1 changed file with 19 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 @@ -8,22 +8,37 @@ case class DatabaseConnection() object DatabaseConnection: given DatabaseConnection = DatabaseConnection() // single-dependency "primitive" environments type MonadEnv[F[_], A] = Monad[F] ?=> F[A] type DatabaseEnv[A] = DatabaseConnection ?=> A // composing envs by nesting // bothe are equivalent! type Env[F[_], A] = MonadEnv[F, DatabaseEnv[A]] type Env2[F[_], A] = DatabaseEnv[MonadEnv[F, A]] // multi-dependency environments // both are equivalent! type Env3[F[_], A] = (DatabaseConnection, Monad[F]) ?=> F[A] type Env4[F[_], A] = (Monad[F], DatabaseConnection) ?=> F[A] // need Env1 def findAllFrunfles[F[_]]: Env[F, List[Frunfles]] = Monad[F].pure(List.empty) def findFrunflesById[F[_]](id: Long): Env[F, Option[Frunfles]] = Monad[F].pure(None) // need Env2 def findFrunflesByValue[F[_]](value: String): Env2[F, Option[Frunfles]] = Monad[F].pure(None) def insertFrunfles[F[_]](f: Frunfles): Env2[F, Unit] = Monad[F].pure(()) // need Env3 def updateFrunfles[F[_]](f: Frunfles): Env3[F, Unit] = Monad[F].pure(()) // need Env4 def deleteFrunfles[F[_]](id: Long): Env4[F, Unit] = Monad[F].pure(()) // nesting order does not matter! // parameter order does not matter! // mixing different envs does not matter! val res: IO[Unit] = for _ <- insertFrunfles[IO](Frunfles(1L, "frunfles")) -
programaker created this gist
May 28, 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,35 @@ import cats.Monad import cats.effect.IO import cats.effect.unsafe.implicits.global case class Frunfles(id: Long, name: String) case class DatabaseConnection() object DatabaseConnection: given DatabaseConnection = DatabaseConnection() type MonadR[F[_], A] = Monad[F] ?=> F[A] type DatabaseR[A] = DatabaseConnection ?=> A type Env[F[_], A] = MonadR[F, DatabaseR[A]] type Env2[F[_], A] = DatabaseR[MonadR[F, A]] type Env3[F[_], A] = (DatabaseConnection, Monad[F]) ?=> F[A] type Env4[F[_], A] = (Monad[F], DatabaseConnection) ?=> F[A] def findAllFrunfles[F[_]]: Env[F, List[Frunfles]] = Monad[F].pure(List.empty) def findFrunflesById[F[_]](id: Long): Env[F, Option[Frunfles]] = Monad[F].pure(None) def findFrunflesByValue[F[_]](value: String): Env2[F, Option[Frunfles]] = Monad[F].pure(None) def insertFrunfles[F[_]](f: Frunfles): Env2[F, Unit] = Monad[F].pure(()) def updateFrunfles[F[_]](f: Frunfles): Env3[F, Unit] = Monad[F].pure(()) def deleteFrunfles[F[_]](id: Long): Env4[F, Unit] = Monad[F].pure(()) val res: IO[Unit] = for _ <- insertFrunfles[IO](Frunfles(1L, "frunfles")) f <- findFrunflesById[IO](1L) _ <- updateFrunfles[IO](Frunfles(1L, "sbrubbles")) _ <- deleteFrunfles[IO](1L) yield () val fs = findAllFrunfles[IO].unsafeRunSync()