Showoff code that I probably wouldn't use on production, but looks smarter than whatever stuff is actually required in our everyday coding :P
// | |
// @author: Mateusz Kubuszok | |
// | |
// requirements: ammonite 1.1.0 | |
// usage: run `amm` and copy paste into REPL | |
import $ivy.`org.typelevel::cats-core:1.3.1`, cats._, cats.syntax.all._ | |
import $ivy.`org.typelevel::cats-effect:1.0.0`, cats.effect._, cats.effect.syntax._ | |
import $ivy.`io.circe::circe-core:0.9.3`, io.circe._, io.circe.syntax._ | |
import $ivy.`io.circe::circe-generic:0.9.3`, io.circe.generic.auto._ | |
import $ivy.`io.circe::circe-parser:0.9.3`, io.circe.parser._ | |
import $ivy.`io.scalaland::pulp:0.0.5`, io.scalaland.pulp._ | |
import $ivy.`io.monix::monix:3.0.0-M3`, monix.eval._, monix.execution.Scheduler.Implicits.global | |
interp.load.plugin.ivy("org.scalamacros" % "paradise_2.12.4" % "2.1.1") | |
final case class User(name: String, surname: String, email: String) | |
{ | |
@ImplementedAs[UserRepoInMemory] | |
trait UserRepo { | |
def fetchByEmail(email: String): Option[User] | |
def save(user: User): Unit | |
} | |
@Singleton | |
class UserRepoInMemory extends UserRepo { | |
private val users = scala.collection.mutable.Map.empty[String, User] | |
def fetchByEmail(email: String): Option[User] = users.get(email) | |
def save(user: User): Unit = users += (user.email -> user) | |
} | |
} | |
@Wired | |
class UserServices[F[_]: Sync](repo: UserRepo) { | |
def parseJson(user: String): F[Option[User]] = Sync[F].delay(decode[User](user).toOption) | |
def asJson(user: User): F[String] = Sync[F].delay(user.asJson.noSpaces) | |
def fetchByEmail(email: String): F[Option[User]] = Sync[F].delay(repo.fetchByEmail(email)) | |
def save(user: User): F[Unit] = Sync[F].delay(repo.save(user)) | |
} | |
@Wired | |
class Program[F[_]: Monad](userServices: UserServices[F]) { | |
def store(json: String): F[Unit] = for { | |
parsed <- userServices.parseJson(json) | |
_ <- parsed.map(userServices.save).getOrElse(().pure[F]) | |
} yield () | |
def retrieve(email: String): F[String] = for { | |
userOpt <- userServices.fetchByEmail(email) | |
json <- userOpt.map(userServices.asJson _).getOrElse(Json.obj().noSpaces.pure[F]) | |
} yield json | |
} | |
// synchronously parse json, and store User to in-memory repo | |
Provider.get[Program[Coeval]].store("""{"name":"John","surname":"Smith","email":"john.smith@mail.com"}""").value | |
// asynchronously retrieve user from in-memory repo and serialize it | |
Provider.get[Program[Task]].retrieve("john.smith@mail.com").runAsync.onComplete(println) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Over-engineered showoff code. Its main principles are: