![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
import cats._ import cats.data._ import cats.implicits._ import scala.concurrent._ import scala.concurrent.duration.Duration._ import ExecutionContext.Implicits.global object Sk extends App { val PLUS = ((_: Int) + (_: Int)).curried trait Lam_[->>[_, _]] { def app[E, A, B]: E ->> (A => B) => E ->> A => E ->> B def fun[A, B]: (A => B) => A ->> (A => B) def lam[A, B]: (A ->> A => A ->> B) => A ->> B } trait Lam[F[_]] extends Lam_[Kleisli[F, ?, ?]] implicit def lama[F[_] : Applicative]: Lam[F] = new Lam[F] { def AP[E] = Applicative[Kleisli[F, E, ?]] def app[E, A, B] = AP[E].ap[A, B] def fun[A, B] = AP[A].pure[A => B] def lam[A, B] = _ (Kleisli.ask[F, A]) } object Lam { def apply[F[_] : Lam] = implicitly[Lam[F]] def app[F[_] : Lam, E, A, B](f: Kleisli[F, E, (A => B)]) (a: Kleisli[F, E, A]) = Lam[F].app(f)(a) def fun[F[_] : Lam, A, B](f: A => B) = Lam[F].fun(f) def lam[F[_] : Lam, A, B](f: Kleisli[F, A, A] => Kleisli[F, A, B]) = Lam[F].lam(f) } import Lam._ def answer[F[_] : Lam]: Kleisli[F, Int, Int] = lam(x => app(app(fun(PLUS))(x))(x)) def main[F[_] : Lam : Functor] = answer[F].map(println) answer[Id].apply(21) Await.ready(main[Future].apply(21), Inf) }