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) }
import cats._ import cats.data._ import cats.arrow._ 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 SK_[->>[_, _]] { def S[E, A, B]: E ->> (A => B) => E ->> A => E ->> B def K[E, A]: (E => A) => E ->> (E => A) def I[A]: A ->> A } object SK_ { def apply[->>[_, _] : SK_] = implicitly[SK_[->>]] def S[->>[_, _] : SK_, E, A, B](f: E ->> (A => B)) (a: E ->> A) = SK_[->>].S(f)(a) def K[->>[_, _] : SK_, E, A](f: E => A) = SK_[->>].K(f) def I[->>[_, _] : SK_, A] = SK_[->>].I[A] } implicit def sk_[->>[_, _] : Arrow]: SK_[->>] = new SK_[->>] { val arrow = Arrow[->>] def S[E, A, B] = f => a => arrow.lift((e: E) => (e, e)) >>> (f.first >>> a.second) >>> arrow.lift(fa => fa._1(fa._2)) def K[E, A] = a => arrow.lift((_: E) => a) def I[A] = arrow.id[A] } trait SK[F[_]] extends SK_[Kleisli[F, ?, ?]] object SK { def apply[F[_] : SK] = implicitly[SK[F]] def S[F[_] : SK, E, A, B](f: Kleisli[F, E, (A => B)]) (a: Kleisli[F, E, A]) = SK[F].S(f)(a) def K[F[_] : SK, E, A](f: E => A) = SK[F].K(f) def I[F[_] : SK, A] = SK[F].I[A] } implicit def ska[F[_] : Applicative]: SK[F] = new SK[F] { def AP[E] = Applicative[Kleisli[F, E, ?]] def S[E, A, B] = AP[E].ap[A, B] def K[E, A] = AP[E].pure[E => A] def I[A] = Kleisli.ask[F, A] } import SK._ def answer[F[_] : SK] = S(S(K(PLUS))(I))(I) def main[F[_] : SK : Functor] = answer[F].map(println) main[Id].apply(21) Await.ready(main[Future].apply(21), Inf) }
and still SK
Nov. 18th, 2016 12:07 amimport 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 SK[F[_]] { type ->>[A, B] = Kleisli[F, A, B] def S[E, A, B]: E ->> (A => B) => E ->> A => E ->> B def K[E, A]: (E => A) => E ->> (E => A) def I[A]: A ->> A } object SK { def apply[F[_] : SK] = implicitly[SK[F]] def S[F[_] : SK, E, A, B](f: SK[F]# ->>[E, A => B]) (a: SK[F]# ->>[E, A]) = SK[F].S(f)(a) def K[F[_] : SK, E, A](f: E => A) = SK[F].K(f) def I[F[_] : SK, A] = SK[F].I[A] } implicit def ska[F[_] : Applicative]: SK[F] = new SK[F] { def AP[E] = Applicative[E ->> ?] def S[E, A, B] = AP[E].ap[A, B] def K[E, A] = AP[E].pure[E => A] def I[A] = Kleisli.ask[F, A] } import SK._ def answer[F[_] : SK] = S(S(K(PLUS))(I))(I) def main[F[_] : SK : Functor] = answer[F].map(println) main[Id].apply(21) Await.ready(main[Future].apply(21), Inf) }
import cats._ import cats.data._ import cats.implicits._ import scala.concurrent._ import duration.Duration._ import ExecutionContext.Implicits.global object Sk extends App { val PLUS = ((_: Int) + (_: Int)).curried trait SK[F[_]] { def S[E, A, B]: Kleisli[F, E, A => B] => Kleisli[F, E, A] => Kleisli[F, E, B] def K[E, A]: (E => A) => Kleisli[F, E, E => A] def I[A]: Kleisli[F, A, A] } object SK { def apply[F[_] : SK] = implicitly[SK[F]] } implicit def ska[F[_] : Applicative]: SK[F] = new SK[F] { def AP[E] = Applicative[Kleisli[F, E, ?]] def S[E, A, B] = AP[E].ap[A, B] def K[E, A] = AP[E].pure[E => A] def I[A] = Kleisli.ask[F, A] } def answer[F[_] : SK] = { val sk = SK[F] import sk._ S(S(K(PLUS))(I))(I) } def main[F[_] : SK : Functor] = answer[F].map(println) main[Id].apply(21) Await.ready(main[Future].apply(21), Inf) }