Skip to content

Commit

Permalink
Merge pull request #353 from Kevin-Lee/task/352/innerFlatMapF-FOptionA
Browse files Browse the repository at this point in the history
Close #352 - [`extras-cats`] Add `innerFlatMapF` extension method to `F[Option[A]]`
  • Loading branch information
kevin-lee committed Mar 10, 2023
2 parents b5ae863 + 4d918c9 commit 7d7c72c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package extras.cats.syntax

import cats.data.OptionT
import cats.{Applicative, Functor}
import cats.syntax.option._
import cats.{Applicative, Functor, Monad}
import extras.cats.syntax.OptionSyntax._

/** @author Kevin Lee
Expand Down Expand Up @@ -51,6 +52,9 @@ object OptionSyntax {
@inline def innerFlatMap[B](f: A => Option[B])(implicit F: Functor[F]): F[Option[B]] =
F.map(fOfOption)(_.flatMap(f))

@inline def innerFlatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): F[Option[B]] =
F.flatMap(fOfOption)(oa => oa.fold(F.pure(none[B]))(f))

}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package extras.cats.syntax

import cats.{Applicative, Functor}
import cats.{Applicative, Functor, Monad}
import cats.syntax.option.*
import cats.data.OptionT

/** @author Kevin Lee
Expand Down Expand Up @@ -33,6 +34,9 @@ trait OptionSyntax {
inline def innerFlatMap[B](f: A => Option[B])(using F: Functor[F]): F[Option[B]] =
F.map(fOfOption)(_.flatMap(f))

inline def innerFlatMapF[B](f: A => F[Option[B]])(using F: Monad[F]): F[Option[B]] =
F.flatMap(fOfOption)(oa => oa.fold(F.pure(none[B]))(f))

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ object OptionSyntaxSpec extends Properties {
"test F[Option[A]].innerFlatMap(A => Option[B]): F[Option[B]]",
FOfOptionInnerOpsSpec.testInnerFlatMap,
),
property(
"test F[Option[A]].innerFlatMapF(A => F[Option[B]]): F[Option[B]]",
FOfOptionInnerOpsSpec.testInnerFlatMapF,
),
)

object OptionTFOptionOpsSpec {
Expand Down Expand Up @@ -311,6 +315,20 @@ object OptionSyntaxSpec extends Properties {
.map(actual => actual ==== expected)
}.unsafeRunSync()

def testInnerFlatMapF: Property =
for {
optionN <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).option.log("optionN")
} yield {
val f: Int => Option[Int] = n => (n * 2).some

val input = fab[IO, Int](optionN)
val expected = optionN.flatMap(f)

input
.innerFlatMapF(a => IO.pure(f(a)))
.map(actual => actual ==== expected)
}.unsafeRunSync()

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ object OptionSyntaxSpec extends Properties {
"test F[Option[A]].innerFlatMap(A => Option[B]): F[Option[B]]",
FOfOptionInnerOpsSpec.testInnerFlatMap,
),
property(
"test F[Option[A]].innerFlatMapF(A => F[Option[B]]): F[Option[B]]",
FOfOptionInnerOpsSpec.testInnerFlatMapF,
),
)

object OptionTFOptionOpsSpec {
Expand Down Expand Up @@ -318,6 +322,20 @@ object OptionSyntaxSpec extends Properties {
.map(actual => actual ==== expected)
}.unsafeRunSync()

def testInnerFlatMapF: Property =
for {
optionN <- Gen.int(Range.linear(Int.MinValue, Int.MaxValue)).option.log("optionN")
} yield {
val f: Int => Option[Int] = n => (n * 2).some

val input = fab[IO, Int](optionN)
val expected = optionN.flatMap(f)

input
.innerFlatMapF(a => IO.pure(f(a)))
.map(actual => actual ==== expected)
}.unsafeRunSync()

}

}

0 comments on commit 7d7c72c

Please sign in to comment.