Last active
August 29, 2015 14:03
-
-
Save nafg/e8af2dc665da77e9e6ba to your computer and use it in GitHub Desktop.
Limitless Applicative builder
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
trait ApType { | |
import scala.language.higherKinds | |
type FS[+Z] | |
} | |
trait ApTypeOne[A] extends ApType { | |
type FS[+Z] = A => Z | |
} | |
trait ApTypeMore[A, N <: ApType] extends ApType { | |
type FS[+Z] = A => N#FS[Z] | |
} | |
import scala.language.higherKinds | |
trait Applicative[M[_]] { | |
def apply[A, B](f: M[A => B])(a: M[A]): M[B] | |
def point[A](a: => A): M[A] | |
} | |
trait ApBase[M[_], AT <: ApType] { | |
implicit def m: Applicative[M] | |
def apply[Z](f: M[AT#FS[Z]]): M[Z] | |
def applyPoint[Z](f: AT#FS[Z]): M[Z] = apply(m.point(f)) | |
def :@:[B](b: M[B]): ApBase[M, ApTypeMore[B, AT]] = new ApMore[M, B, AT](b, this) | |
} | |
implicit class ApOne[M[_], A](val in: M[A])(implicit val m: Applicative[M]) extends ApBase[M, ApTypeOne[A]] { | |
override def apply[Z](f: M[A => Z]): M[Z] = m.apply(f)(in) | |
} | |
class ApMore[M[_], A, N <: ApType](val a: M[A], val next: ApBase[M, N])(implicit val m: Applicative[M]) extends ApBase[M, ApTypeMore[A, N]] { | |
override def apply[Z](f: M[A => N#FS[Z]]): M[Z] = next.apply(m.apply(f)(a)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment