Skip to content

Instantly share code, notes, and snippets.

View kubukoz's full-sized avatar
😱
I might take a week to respond. Or a month.

Jakub Kozłowski kubukoz

😱
I might take a week to respond. Or a month.
View GitHub Profile
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
val ipValidationF: F[ValidatedNel[PVError, String]] =
clientIp
.toValidNel(PVError.noIp)
.traverse(checkIp(_, hostname, normalizedPath))
.map(_.andThen(identity)
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
val pathValidationF: F[ValidatedNel[PVError, String]] =
pageExists(hostname, normalizedPath).map(
Validated.condNel(_, normalizedPath, PVError.pageNotFound))
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
(uuidF, currentTimeF, ipValidationF, pathValidationF).traverseN {
(uuid, currentTime, ipValidation, pathValidation) => ...
}
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
val timestampV: ValidatedNel[PVError, OffsetDateTime] = event
.displayedAt
.valid
.ensure(PVError.invalidTimestamp)(_.isBefore(currentTime))
.toValidatedNel
(
uuid.valid,
pathValidation,
timestampV,
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
(uuidF, currentTimeF, ipValidationF, pathValidationF).traverseN {
(uuid, currentTime, ipValidation, pathValidation) =>
val timestampV = event
.displayedAt
.valid
.ensure(PVError.invalidTimestamp)(_.isBefore(currentTime))
.toValidatedNel
(
uuid.valid,
@kubukoz
kubukoz / post.json
Created May 16, 2018 13:10
the description for this gist
| Column | Type |
------------------------------------------+
| id | uuid |
| path | text |
| displayed_at | timestamp with time zone |
| hostname | text |
| client_ip | text |
@kubukoz
kubukoz / post.scala
Created May 16, 2018 13:10
the description for this gist
def persist(pageView: PageView): F[Unit] =
sql"""
insert into page_views(id, path, displayed_at, hostname, client_ip) value
(${pageView.id}, ${pageView.path}, ${pageView.displayedAt}, ${pageView.hostname}, ${pageView.clientIp})
""".update.run.transact(transactor).void
def sideEffecting(): Map[String, List[String]] = { println("bazinga"); Map("a" -> List("a", "b")) }
//doesn't print anything here
val x1: String => List[String] = sideEffecting().getOrElse(_, Nil)
//but it'll print bazinga any time you call one of these:
x1("a") //here
x1("a") //also here
x1("b") //here too
@kubukoz
kubukoz / HasKF.scala
Last active June 9, 2018 17:22
One of the many workarounds for "implicit type parameters" in Scala
class HasKF[F[_]] private {
type KF[A, B] = Kleisli[F, A, B]
}
object HasKF {
private val s: HasKF[Id] = new HasKF[Id]
def apply[F[_]]: HasKF[F] = s.asInstanceOf[HasKF[F]]
}
class AService[F[_] : Applicative] {
@kubukoz
kubukoz / SlickRunIO.scala
Last active January 14, 2019 16:58
SlickRunIO.scala
trait SlickRunIOImplicits { self: API =>
implicit class SlickRunIO(db: Database) {
/** Return an effect that runs a DB action. */
def runIO[R](a: DBIOAction[R, NoStream, Nothing])(implicit cs: ContextShift[IO]): IO[R] =
IO.fromFuture(IO(db.run(a))).guarantee(cs.shift)
/** Return an effect that runs a DB action with timing metrics collected */
def runIO[R](a: DBIOAction[R, NoStream, Nothing], timerName: String)(
implicit metric: MetricsF