Skip to content

Instantly share code, notes, and snippets.

@MateuszKubuszok
Last active May 8, 2019 13:24
Show Gist options
  • Save MateuszKubuszok/595b1b6cb409f2ef0cbf5d5c914e1e1b to your computer and use it in GitHub Desktop.
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
//
// @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)
@MateuszKubuszok
Copy link
Author

MateuszKubuszok commented Jan 25, 2018

Over-engineered showoff code. Its main principles are:

  • show that I know Scala a bit
  • prove that I understand implicits, type bounds, type-classes
  • can use shapeless and macro annotations (Pulp is my library)
  • show that I understand TTFI
  • encode some retarded domain
  • run it all, because it is a mockup but a working mockup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment