-
-
Save ahoy-jon/7d24ad00ea61fa13c5c4b85ceb5e1f55 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
package cats | |
import cats.Ask.WithS | |
import kyo.* | |
import kyo.TypeMap | |
import kyo.kernel.ContextEffect | |
sealed trait Ask[R[_[_]]] extends ContextEffect[TypeMap[R[Ask.AnyS]]] | |
object Ask: | |
private trait AnyT[AnyF[_]] | |
private def erasedTag[R[_[_]]] = Tag[Ask[AnyT]].asInstanceOf[Tag[Ask[R]]] | |
type WithS[-S] = [A] =>> A < S | |
type Fix[R[_[_]]] = R[WithS[Ask[R]]] | |
private[cats] type AnyS = WithS[Any] | |
def use[R[_[_]]](using frame: Frame)[A, S](f: Fix[R] => A < S)(using tag: Tag[R[AnyS]]): A < (Ask[R] & S) = | |
ContextEffect.suspendWith(erasedTag[R]): map => | |
f(map.asInstanceOf[TypeMap[R[AnyS]]].get(using tag).asInstanceOf[Fix[R]]) | |
def get[R[_[_]]](using frame: Frame, tag: Tag[R[AnyS]]): Fix[R] < Ask[R] = use[R](identity) | |
def run[R[_[_]], S1](r: R[WithS[S1]])[A, S2](a: A < (Ask[R] & S2))(using tag: Tag[R[AnyS]], frame: Frame): A < (S1 & S2) = | |
val env: TypeMap[R[AnyS]] = TypeMap(r.asInstanceOf) | |
ContextEffect.handle(erasedTag[R], env, _.union(env))(a) | |
trait Console[F[_]]: | |
def read: F[String] | |
def printLine(line: String): F[Unit] | |
trait Logger[F[_]]: | |
def log(level: String)(message: String): F[Unit] | |
val comp: String < (Ask[Console] & Ask[Logger] & Sync) = | |
for | |
console <- Ask.get[Console] | |
logger <- Ask.get[Logger] | |
_ <- logger.log("Debug")("Start teletype example") | |
_ <- kyo.Console.printLine("Hello from Kyo") | |
_ <- console.printLine("Hello, World!") | |
_ <- console.printLine("What is your name?") | |
name <- console.read | |
_ <- console.printLine(s"Hello $name!") | |
yield name | |
val soutConsole: Console[Ask.WithS[Sync]] = new Console[WithS[Sync]]: | |
override def read: String < Sync = kyo.Console.readLine.orPanic | |
override def printLine(line: String): Unit < Sync = kyo.Console.printLine(line) | |
val soutLogger: Logger[Ask.WithS[Sync]] = new Logger[WithS[Sync]]: | |
override def log(level: String)(message: String): Unit < Sync = kyo.Console.printLine(s"[$level]: $message") | |
object App extends KyoApp: | |
comp.handle( | |
Ask.run(soutLogger), | |
Ask.run(soutConsole), | |
run | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment