Last active
May 8, 2019 13:24
-
-
Save MateuszKubuszok/595b1b6cb409f2ef0cbf5d5c914e1e1b to your computer and use it in GitHub Desktop.
Showoff code that I probably wouldn't use on production, but looks smarter than whatever stuff is actually required in our everyday coding :P
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
// | |
// @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":"[email protected]"}""").value | |
// asynchronously retrieve user from in-memory repo and serialize it | |
Provider.get[Program[Task]].retrieve("[email protected]").runAsync.onComplete(println) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Over-engineered showoff code. Its main principles are: