diff --git a/kernel-laws/shared/src/test/scala/cats/kernel/laws/LawTests.scala b/kernel-laws/shared/src/test/scala/cats/kernel/laws/LawTests.scala index c2dbfe6a5e..47aa13cfa0 100644 --- a/kernel-laws/shared/src/test/scala/cats/kernel/laws/LawTests.scala +++ b/kernel-laws/shared/src/test/scala/cats/kernel/laws/LawTests.scala @@ -229,6 +229,15 @@ class Tests extends TestsConfig with DisciplineSuite { checkAll("BoundedEnumerable[Int]", BoundedEnumerableTests[Int].boundedEnumerable) checkAll("BoundedEnumerable[Char]", BoundedEnumerableTests[Char].boundedEnumerable) checkAll("BoundedEnumerable[Long]", BoundedEnumerableTests[Long].boundedEnumerable) + checkAll("BoundedEnumerable.reverse(BoundedEnumerable[Int])", + BoundedEnumerableTests(BoundedEnumerable.reverse(BoundedEnumerable[Int])).boundedEnumerable + ) + checkAll( + "BoundedEnumerable.reverse(BoundedEnumerable.reverse(BoundedEnumerable[Int]))", + BoundedEnumerableTests( + BoundedEnumerable.reverse(BoundedEnumerable.reverse(BoundedEnumerable[Int])) + ).boundedEnumerable + ) checkAll("Monoid[String]", MonoidTests[String].monoid) checkAll("Monoid[String]", SerializableTests.serializable(Monoid[String])) diff --git a/kernel/src/main/scala/cats/kernel/Enumerable.scala b/kernel/src/main/scala/cats/kernel/Enumerable.scala index 96753108eb..3c68cb004e 100644 --- a/kernel/src/main/scala/cats/kernel/Enumerable.scala +++ b/kernel/src/main/scala/cats/kernel/Enumerable.scala @@ -79,6 +79,21 @@ object BoundedEnumerable { cats.kernel.instances.char.catsKernelStdOrderForChar @inline def apply[A](implicit e: BoundedEnumerable[A]): BoundedEnumerable[A] = e + + /** + * Defines a `BoundedEnumerable[A]` from the given enumerable such that + * all arrows / successor functions switch direction. + */ + def reverse[@sp A](e: BoundedEnumerable[A]): BoundedEnumerable[A] = + new BoundedEnumerable[A] { + override def order: Order[A] = Order.reverse(e.order) + + override def partialNext(a: A): Option[A] = e.partialPrevious(a) + override def partialPrevious(a: A): Option[A] = e.partialNext(a) + + override def minBound: A = e.maxBound + override def maxBound: A = e.minBound + } } trait LowerBoundedEnumerable[@sp A] extends PartialNextLowerBounded[A] with Next[A] {