Skip to content

Instantly share code, notes, and snippets.

@notxcain
Last active August 29, 2018 19:45
Show Gist options
  • Save notxcain/36eb32687b6b7ed83177721746d368a1 to your computer and use it in GitHub Desktop.
Save notxcain/36eb32687b6b7ed83177721746d368a1 to your computer and use it in GitHub Desktop.
import cats.implicits._
import cats.{ Applicative, Monad }
// Операции над контекстом
trait ContextWriter[F[_]] {
def put(key: String, value: String): F[Unit]
}
// Сервисы
class ServiceA[F[_]: Monad](context: ContextWriter[F]) {
def someSimpleOperation: Int = 1
def someLongOperation: F[Int] =
someSimpleOperation
.pure[F]
.flatMap { res =>
context.put("ServiceA.step1", res.toString)
.as(res * Random.nextInt(10))
}
.flatMap { res =>
context.put("ServiceA.step2", res.toString)
.as(res - Random.nextInt(5))
}
}
class ServiceB[F[_]: Monad](serviceA: ServiceA[F], context: ContextWriter[F]) {
def someOperationWithoutServiceA: Int = 1
def someOperationWithServiceA: F[Boolean] =
serviceA.someLongOperation.flatMap {
case res if res % 2 == 0 =>
context.put("ServiceB.res", "even").as(true)
case res =>
context.put("ServiceB.res", "odd").as(false)
}
}
// Бойлерплейт
type Context = Map[String, String]
class WriterTContextWriter[F[_]: Applicative] extends ContextWriter[WriterT[F, Context, ?]] {
def put(key: String, value: String): WriterT[F, Context, Unit] =
WriterT.tell(Map(key, value))
}
// Вайринг
val contextWriter = new WriterTContextWriter[Future]
val serviceA: ServiceA[WriterT[Future, Context, ?]] = new ServiceA(contextWriter)
val serviceB: ServiceB[WriterT[Future, Context, ?]] = new ServiceB(serviceA, contextWriter)
// Результат
val result: Future[(Context, Boolean)] = serviceB.someOperationWithServiceA.run
result.onComplete {
case Success((context, result)) =>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment