SK lambda

Nov. 23rd, 2016 02:34 am
xacid: (Default)

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)

}

SK arrows

Nov. 19th, 2016 09:38 pm
xacid: (Default)
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)

}

xacid: (Default)
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 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)

}

more SK

Nov. 17th, 2016 07:28 pm
xacid: (Default)
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)

}

Typed SK

Nov. 17th, 2016 01:48 am
xacid: (Default)
object Sk extends App {
  def S[X, Y, Z] = (x: Z => Y => X) =>
    (y: Z => Y) => (z: Z) => x(z)(y(z))

  def K[X, Y] = (x: Y => X) => (y: Y) => x

  def I[X] = (x: X) => x

  val PLUS = ((_: Int) + (_: Int)).curried

  val main = S(S(K(PLUS))(I))(I)

  println(main(21))
}

Profile

xacid: (Default)
xacid

August 2017

S M T W T F S
  123 45
67891011 12
13 141516171819
20212223242526
2728293031  

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 24th, 2017 01:57 pm
Powered by Dreamwidth Studios