SK lambda

Nov. 23rd, 2016 02:34 am
xacid: (Default)
[personal profile] xacid

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)

}

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

xacid: (Default)
xacid

April 2021

S M T W T F S
    123
45678910
11121314151617
18192021222324
252627282930 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 20th, 2025 06:09 pm
Powered by Dreamwidth Studios