Last active
August 31, 2018 09:01
-
-
Save Tvaroh/efa364074626ba051dc048ae3a53fb8b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import cats.data.ReaderT | |
import cats.implicits._ | |
import cats.{Applicative, Functor} | |
trait ContextRead[F[_], Ctx] { | |
def read: F[Ctx] | |
} | |
object ContextRead { | |
def apply[F[_], Ctx](implicit context: ContextRead[F, Ctx]): ContextRead[F, Ctx] = implicitly | |
def reader[F[_]: Applicative, Ctx]: ContextRead[ReaderT[F, Ctx, ?], Ctx] = new ReaderContextRead | |
private class ReaderContextRead[F[_]: Applicative, Ctx] extends ContextRead[ReaderT[F, Ctx, ?], Ctx] { | |
override def read: ReaderT[F, Ctx, Ctx] = | |
ReaderT.ask[F, Ctx] | |
} | |
implicit def functorInstance[F[_]: Functor, Ctx]: Functor[ContextRead[F, ?]] = new ContextReadFunctor | |
private class ContextReadFunctor[F[_]: Functor, Ctx] extends Functor[ContextRead[F, ?]] { | |
override def map[A, B](fa: ContextRead[F, A])(f: A => B): ContextRead[F, B] = | |
new ContextRead[F, B] { | |
override def read: F[B] = fa.read.map(f) | |
} | |
} | |
} | |
trait ContextScope[F[_], Ctx] { | |
def scope[T](f: Ctx => Ctx)(ft: F[T]): F[T] | |
} | |
object ContextScope { | |
def apply[F[_], Ctx](implicit context: ContextScope[F, Ctx]): ContextScope[F, Ctx] = implicitly | |
def reader[F[_]: Applicative, Ctx]: ContextScope[ReaderT[F, Ctx, ?], Ctx] = new ReaderContextScope | |
private class ReaderContextScope[F[_]: Applicative, Ctx] extends ContextScope[ReaderT[F, Ctx, ?], Ctx] { | |
override def scope[T](f: Ctx => Ctx)(ft: ReaderT[F, Ctx, T]): ReaderT[F, Ctx, T] = | |
ReaderT.local(f)(ft) | |
} | |
} | |
trait Context[F[_], Ctx] extends ContextRead[F, Ctx] with ContextScope[F, Ctx] | |
object Context { | |
def apply[F[_], Ctx](implicit context: Context[F, Ctx]): Context[F, Ctx] = implicitly | |
def reader[F[_]: Applicative, Ctx]: Context[ReaderT[F, Ctx, ?], Ctx] = new ReaderContext | |
private class ReaderContext[F[_]: Applicative, Ctx] extends Context[ReaderT[F, Ctx, ?], Ctx] { | |
override def read: ReaderT[F, Ctx, Ctx] = | |
contextRead.read | |
override def scope[T](f: Ctx => Ctx)(ft: ReaderT[F, Ctx, T]): ReaderT[F, Ctx, T] = | |
contextScope.scope(f)(ft) | |
private val contextRead = ContextRead.reader[F, Ctx] | |
private val contextScope = ContextScope.reader[F, Ctx] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment