Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
trait Monad[F[_]] {
def point[A](a: A): F[A]
def bind[A, B](fa: F[A])(f: A => F[B]): F[B]
def map[A, B](fa: F[A])(f: A => B): F[B] =
bind(fa)(a => point(f(a))
def join[A](ffa: F[F[A]): F[A] =
bind(ffa)(fa => fa)
}
sealed trait Free[F[_], A] {
def point[F[_]](a: A): Free[F, A] = Point(a)
def flatMap[B](f: A => Free[F, B])(implicit functor: Functor[F]): Free[F, B] =
this match {
case Point(a) => f(a)
case Join(ffa) => Join(ffa.map(fa => fa.flatMap(f)))
}
def map[B](f: A => B)(implicit functor: Functor[F]): Free[F, B] =
flatMap(a => Point(f(a)))
}
case class Point[F[_], A](a: A) extends Free[F, A]
case class Join[F[_], A](ff: F[Free[F, A]]) extends Free[F, A]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment