Monad is Applicative and Bind. With that we deal with:

def ap[A,B](fa:  F[A])(f:  F[A  B]): F[B]
def map[A, B](fa: F[A])(f: A  B): F[B]

from Apply

def point[A](a: => A): F[A]
override def map[A, B](fa: F[A])(f: A => B): F[B] = ap(fa)(point(f))

from Applicative

def bind[A, B](fa: F[A])(f: A => F[B]): F[B]
override def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B] = bind(f)(map(fa))

from Bind.

Note that in Applicative, map method is implemented using ap method and in Bind, ap is implemented using bind method. With that, two methods that are left to be implemented for a Monad are point and bind.

Having those we can derive other methods for monad.

  • liftM. List a monad into a different monad.
  • whileM. Executes action while predicate is true and collects the results into MonadPlus.
  • whileM_. Executes action while predicate is true.
  • unitlM. Until version of WhileM.
  • unitlM_. Until version of WhileM_.
  • iterateWhile. Similar to whileM_ except predicate is A => Boolean instead of F[Boolean].
  • iterateUntil. Similar to unitlM_ except predicate is A => Boolean instead of F[Boolean].