Skip to content

Instantly share code, notes, and snippets.

@hiramekun
Last active April 20, 2022 02:14
Show Gist options
  • Save hiramekun/f808f1e2eee6b6b743da66db40a43d14 to your computer and use it in GitHub Desktop.
Save hiramekun/f808f1e2eee6b6b743da66db40a43d14 to your computer and use it in GitHub Desktop.
Option monad example using cats.Monad.
import cats.Monad
import scala.annotation.tailrec
object MyOption {
implicit def optionMonad: Monad[MyOption] =
new Monad[MyOption] {
override def pure[A](x: A): MyOption[A] = MySome(x)
override def flatMap[A, B](fa: MyOption[A])(f: A => MyOption[B]): MyOption[B] = fa match {
case MySome(value) => f(value)
case MyNone() => MyNone()
}
@tailrec
override def tailRecM[A, B](a: A)(f: A => MyOption[Either[A, B]]): MyOption[B] = f(a) match {
case MySome(Right(value)) => MySome(value)
case MySome(Left(value)) => tailRecM(value)(f)
case MyNone() => MyNone()
}
}
}
sealed class MyOption[A](implicit val optionMonad: Monad[MyOption]) {
def flatMap[B](f: A => MyOption[B]): MyOption[B] = optionMonad.flatMap(this)(f)
def map[B](f: A => B): MyOption[B] = optionMonad.map(this)(f)
}
case class MySome[A](value: A) extends MyOption[A]
case class MyNone[A]() extends MyOption[A]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment