Skip to content

Instantly share code, notes, and snippets.

@tonymorris
Last active August 29, 2015 14:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tonymorris/e66a5efc7412c172b8c3 to your computer and use it in GitHub Desktop.
Save tonymorris/e66a5efc7412c172b8c3 to your computer and use it in GitHub Desktop.
import scala.language.higherKinds // lol
trait Functor[F[_]] {
def fmap[A, B](f: A => B): F[A] => F[B]
}
trait Apply[F[_]] {
def ap[A, B](f: F[A => B]): F[A] => F[B]
}
trait Applicative[F[_]] {
val apply: Apply[F]
def ap[A, B](f: F[A => B]): F[A] => F[B] =
apply.ap(f)
def pure[A](a: A): F[A]
def functor: Functor[F] =
new Functor[F] {
def fmap[A, B](f: A => B): F[A] => F[B] =
ap(pure(f))
}
def fmap[A, B](f: A => B): F[A] => F[B] =
functor.fmap(f)
}
trait Bind[F[_]] {
def bnd[A, B](f: A => F[B]): F[A] => F[B]
}
trait Monad[F[_]] {
val bind: Bind[F]
def bnd[A, B](f: A => F[B]): F[A] => F[B] =
bind.bnd(f)
val applicative: Applicative[F]
def pure[A](a: A): F[A] =
applicative.pure(a)
def apply: Apply[F] =
applicative.apply
def ap[A, B](f: F[A => B]): F[A] => F[B] =
apply.ap(f)
def functor: Functor[F] =
applicative.functor
def fmap[A, B](f: A => B): F[A] => F[B] =
functor.fmap(f)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment