Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fedesilva/8a7a6ff6851bc08cf913da434d37ae37 to your computer and use it in GitHub Desktop.
Save fedesilva/8a7a6ff6851bc08cf913da434d37ae37 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
//
// @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