Skip to content

Commit

Permalink
Add doctests and Either tests
Browse files Browse the repository at this point in the history
  • Loading branch information
LukaJCB committed Oct 15, 2019
1 parent e249b96 commit 6e7d2b4
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
36 changes: 35 additions & 1 deletion core/src/main/scala/cats/Align.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,64 @@ import cats.data.Ior
/**
* Pairs elements of two structures along the union of their shapes, using `Ior` to hold the results.
*
* Align[List].align(List(1, 2), List(10, 11, 12)) = List(Ior.Both(1, 10), Ior.Both(2, 11), Ior.Right(12))
* Example:
* {{{
* scala> import cats.implicits._
* scala> import cats.data.Ior
* scala> Align[List].align(List(1, 2), List(10, 11, 12))
* res0: List[Ior[Int, Int]] = List(Both(1,10), Both(2,11), Right(12))
* }}}
*/
def align[A, B](fa: F[A], fb: F[B]): F[Ior[A, B]]

/**
* Combines elements similarly to `align`, using the provided function to compute the results.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> Align[List].alignWith(List(1, 2), List(10, 11, 12))(_.mergeLeft)
* res0: List[Int] = List(1, 2, 12)
* }}}
*/
def alignWith[A, B, C](fa: F[A], fb: F[B])(f: Ior[A, B] => C): F[C] =
functor.map(align(fa, fb))(f)

/**
* Align two structures with the same element, combining results according to their semigroup instances.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> Align[List].alignCombine(List(1, 2), List(10, 11, 12))
* res0: List[Int] = List(11, 13, 12)
* }}}
*/
def alignCombine[A: Semigroup](fa1: F[A], fa2: F[A]): F[A] =
alignWith(fa1, fa2)(_.merge)

/**
* Same as `align`, but forgets from the type that one of the two elements must be present.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> Align[List].padZip(List(1, 2), List(10))
* res0: List[(Option[Int], Option[Int])] = List((Some(1),Some(10)), (Some(2),None))
* }}}
*/
def padZip[A, B](fa: F[A], fb: F[B]): F[(Option[A], Option[B])] =
alignWith(fa, fb)(_.pad)

/**
* Same as `alignWith`, but forgets from the type that one of the two elements must be present.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> Align[List].padZipWith(List(1, 2), List(10, 11, 12))(_ |+| _)
* res0: List[Option[Int]] = List(Some(11), Some(13), Some(12))
* }}}
*/
def padZipWith[A, B, C](fa: F[A], fb: F[B])(f: (Option[A], Option[B]) => C): F[C] =
alignWith(fa, fb)(ior => Function.tupled(f)(ior.pad))
Expand Down
4 changes: 4 additions & 0 deletions tests/src/test/scala/cats/tests/EitherSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import cats.data.{EitherT, NonEmptyChain, NonEmptyList, NonEmptySet, Validated}
import cats.laws.discipline._
import cats.kernel.laws.discipline.{EqTests, MonoidTests, OrderTests, PartialOrderTests, SemigroupTests}
import org.scalatest.funsuite.AnyFunSuiteLike
import cats.laws.discipline.arbitrary._

import scala.util.Try

Expand All @@ -17,6 +18,9 @@ class EitherSuite extends CatsSuite {
checkAll("Either[Int, Int]", SemigroupalTests[Either[Int, *]].semigroupal[Int, Int, Int])
checkAll("Semigroupal[Either[Int, *]]", SerializableTests.serializable(Semigroupal[Either[Int, *]]))

checkAll("Either[Int, Int]", AlignTests[Either[Int, *]].align[Int, Int, Int, Int])
checkAll("Align[Either[Int, *]]", SerializableTests.serializable(Align[Either[Int, *]]))

implicit val eq0 = EitherT.catsDataEqForEitherT[Either[Int, *], Int, Int]

checkAll("Either[Int, Int]", MonadErrorTests[Either[Int, *], Int].monadError[Int, Int, Int])
Expand Down

0 comments on commit 6e7d2b4

Please sign in to comment.