Skip to content

Commit

Permalink
Merge pull request #571 from liff/topic/subflatMap
Browse files Browse the repository at this point in the history
Add transform and subflatMap to OptionT and XorT
  • Loading branch information
ceedubs committed Nov 10, 2015
2 parents 502c5fa + d4393aa commit 74acdef
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
6 changes: 6 additions & 0 deletions core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ final case class OptionT[F[_], A](value: F[Option[A]]) {
case None => F.pure(None)
})

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

def subflatMap[B](f: A => Option[B])(implicit F: Functor[F]): OptionT[F, B] =
transform(_.flatMap(f))

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

Expand Down
6 changes: 6 additions & 0 deletions core/src/main/scala/cats/data/XorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ case class XorT[F[_], A, B](value: F[A Xor B]) {
def flatMapF[AA >: A, D](f: B => F[AA Xor D])(implicit F: Monad[F]): XorT[F, AA, D] =
flatMap(f andThen XorT.apply)

def transform[C, D](f: Xor[A, B] => Xor[C, D])(implicit F: Functor[F]): XorT[F, C, D] =
XorT(F.map(value)(f))

def subflatMap[AA >: A, D](f: B => AA Xor D)(implicit F: Functor[F]): XorT[F, AA, D] =
transform(_.flatMap(f))

def map[D](f: B => D)(implicit F: Functor[F]): XorT[F, A, D] = bimap(identity, f)

def leftMap[C](f: A => C)(implicit F: Functor[F]): XorT[F, C, B] = bimap(f, identity)
Expand Down
12 changes: 12 additions & 0 deletions tests/src/test/scala/cats/tests/OptionTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ class OptionTTests extends CatsSuite {
OptionT[Xor[String, ?], Int](xor).show should === ("Xor.Right(Some(1))")
}

test("transform consistent with value.map") {
forAll { (o: OptionT[List, Int], f: Option[Int] => Option[String]) =>
o.transform(f) should === (OptionT(o.value.map(f)))
}
}

test("subflatMap consistent with value.map+flatMap") {
forAll { (o: OptionT[List, Int], f: Int => Option[String]) =>
o.subflatMap(f) should === (OptionT(o.value.map(_.flatMap(f))))
}
}

checkAll("OptionT[List, Int]", MonadCombineTests[OptionT[List, ?]].monad[Int, Int, Int])
checkAll("MonadOptionT[List, ?]]", SerializableTests.serializable(Monad[OptionT[List, ?]]))

Expand Down
12 changes: 12 additions & 0 deletions tests/src/test/scala/cats/tests/XorTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,16 @@ class XorTTests extends CatsSuite {
val xort = XorT.right[Id, String, Int](10)
xort.recoverWith { case "xort" => XorT.right[Id, String, Int](5) } should === (xort)
}

test("transform consistent with value.map") {
forAll { (xort: XorT[List, String, Int], f: String Xor Int => Long Xor Double) =>
xort.transform(f) should === (XorT(xort.value.map(f)))
}
}

test("subflatMap consistent with value.map+flatMap") {
forAll { (xort: XorT[List, String, Int], f: Int => String Xor Double) =>
xort.subflatMap(f) should === (XorT(xort.value.map(_.flatMap(f))))
}
}
}

0 comments on commit 74acdef

Please sign in to comment.