|
1 | 1 | package cats |
2 | 2 |
|
3 | | -import simulacrum.typeclass |
| 3 | +import simulacrum.{noop, typeclass} |
4 | 4 |
|
5 | 5 | /** |
6 | 6 | * A type class abstracting over types that give rise to two independent [[cats.Traverse]]s. |
@@ -61,6 +61,52 @@ import simulacrum.typeclass |
61 | 61 |
|
62 | 62 | override def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D] = |
63 | 63 | bitraverse[Id, A, B, C, D](fab)(f, g) |
| 64 | + |
| 65 | + /** |
| 66 | + * Traverse over the left side of the structure. |
| 67 | + * For the right side, use the standard `traverse` from [[cats.Traverse]]. |
| 68 | + * |
| 69 | + * Example: |
| 70 | + * {{{ |
| 71 | + * scala> import cats.implicits._ |
| 72 | + * |
| 73 | + * scala> val intAndString: (Int, String) = (7, "test") |
| 74 | + * |
| 75 | + * scala> Bitraverse[Tuple2].leftTraverse(intAndString)(i => Option(i).filter(_ > 5)) |
| 76 | + * res1: Option[(Int, String)] = Some((7,test)) |
| 77 | + * |
| 78 | + * scala> Bitraverse[Tuple2].leftTraverse(intAndString)(i => Option(i).filter(_ < 5)) |
| 79 | + * res2: Option[(Int, String)] = None |
| 80 | + * }}} |
| 81 | + */ |
| 82 | + @noop |
| 83 | + def leftTraverse[G[_], A, B, C](fab: F[A, B])(f: A => G[C])(implicit G: Applicative[G]): G[F[C, B]] = |
| 84 | + bitraverse(fab)(f, G.pure(_)) |
| 85 | + |
| 86 | + /** |
| 87 | + * Sequence the left side of the structure. |
| 88 | + * For the right side, use the standard `sequence` from [[cats.Traverse]]. |
| 89 | + * |
| 90 | + * Example: |
| 91 | + * {{{ |
| 92 | + * scala> import cats.implicits._ |
| 93 | + * |
| 94 | + * scala> val optionalErrorRight: Either[Option[String], Int] = Either.right(123) |
| 95 | + * scala> optionalErrorRight.leftSequence |
| 96 | + * res1: Option[Either[String, Int]] = Some(Right(123)) |
| 97 | + * |
| 98 | + * scala> val optionalErrorLeftSome: Either[Option[String], Int] = Either.left(Some("something went wrong")) |
| 99 | + * scala> optionalErrorLeftSome.leftSequence |
| 100 | + * res2: Option[Either[String, Int]] = Some(Left(something went wrong)) |
| 101 | + * |
| 102 | + * scala> val optionalErrorLeftNone: Either[Option[String], Int] = Either.left(None) |
| 103 | + * scala> optionalErrorLeftNone.leftSequence |
| 104 | + * res3: Option[Either[String,Int]] = None |
| 105 | + * }}} |
| 106 | + */ |
| 107 | + @noop |
| 108 | + def leftSequence[G[_], A, B](fgab: F[G[A], B])(implicit G: Applicative[G]): G[F[A, B]] = |
| 109 | + bitraverse(fgab)(identity, G.pure(_)) |
64 | 110 | } |
65 | 111 |
|
66 | 112 | private[cats] trait ComposedBitraverse[F[_, _], G[_, _]] |
|
0 commit comments