Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add foldF, cataF and emptyflatTap to OptionT #3335

Merged
merged 9 commits into from
May 13, 2020
30 changes: 30 additions & 0 deletions core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ final case class OptionT[F[_], A](value: F[Option[A]]) {
def fold[B](default: => B)(f: A => B)(implicit F: Functor[F]): F[B] =
F.map(value)(_.fold(default)(f))

/** Transform this `OptionT[F, A]` into a `F[C]`.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> import cats.data.OptionT
*
* scala> val optionT: OptionT[List, Int] = OptionT[List, Int](List(Some(23), None))
* scala> optionT.foldF(Nil)(v => List(v, v * 2))
* res0: List[Int] = List(23, 46)
* }}}
*/
def foldF[B](default: => F[B])(f: A => F[B])(implicit F: FlatMap[F]): F[B] =
Copy link
Contributor

@diesalbla diesalbla Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def foldF[B](default: => F[B])(f: A => F[B])(implicit F: FlatMap[F]): F[B] =
def foldF[B](ifNone: => F[B])(withSome: A => F[B])(implicit F: FlatMap[F]): F[B] =

Should we add more informative names?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree with your intention (and have hence changed it on flatTapNone – thx), I would value consistency with fold more and keep the parameter names the same.

F.flatMap(value)(_.fold(default)(f))

/**
* Catamorphism on the Option. This is identical to [[fold]], but it only has
* one parameter list, which can result in better type inference in some
Expand All @@ -24,6 +39,14 @@ final case class OptionT[F[_], A](value: F[Option[A]]) {
def cata[B](default: => B, f: A => B)(implicit F: Functor[F]): F[B] =
fold(default)(f)

/**
* Effectful catamorphism on the Option. This is identical to [[foldF]], but it only has
* one parameter list, which can result in better type inference in some
* contexts.
*/
def cataF[B](default: => F[B], f: A => F[B])(implicit F: FlatMap[F]): F[B] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware of the notions of catamorphisms, but is that also a unified term or notion across cats? I can only grep the words def cata in OptionTand in CoFree.

Unless we want to extend the use across the whole of cats, perhaps we should drop them, to avoid confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a cata to fold already, so when seeing foldF, I'd expect cataF there as well. Whether cata should have been introduced with that name in the first place seems to be outside of the scope of this PR…but that's just my two cents.

foldF(default)(f)

def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B] =
OptionT(F.map(value)(_.map(f)))

Expand Down Expand Up @@ -63,6 +86,13 @@ final case class OptionT[F[_], A](value: F[Option[A]]) {
def subflatMap[B](f: A => Option[B])(implicit F: Functor[F]): OptionT[F, B] =
transform(_.flatMap(f))

/**
* Perform an effect if the value inside the is a [[None]], leaving the result untouched. Equivalent to [[orElseF]]
* with an effect returning [[None]] as argument.
*/
def emptyflatTap[B](f: => F[B])(implicit F: Monad[F]): OptionT[F, A] =
ybasket marked this conversation as resolved.
Show resolved Hide resolved
OptionT(F.flatTap(value)(_.fold(F.void(f))(_ => F.unit)))

def getOrElse[B >: A](default: => B)(implicit F: Functor[F]): F[B] =
F.map(value)(_.getOrElse(default))

Expand Down