Skip to content

Commit

Permalink
Add Syntax For Enumerable
Browse files Browse the repository at this point in the history
Also load the existing definitions PartialNext/PartialPrevious into implicit scope.
  • Loading branch information
isomarcte committed Nov 16, 2022
1 parent 51156ef commit 4b0a87b
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ abstract class AllSyntaxBinCompat
with AllSyntaxBinCompat5
with AllSyntaxBinCompat6
with AllSyntaxBinCompat7
with AllSyntaxBinCompat8

trait AllSyntax
extends AlternativeSyntax
Expand Down Expand Up @@ -122,3 +123,10 @@ trait AllSyntaxBinCompat5 extends ParallelBitraverseSyntax
trait AllSyntaxBinCompat6 extends ParallelUnorderedTraverseSyntax

trait AllSyntaxBinCompat7 extends SeqSyntax

trait AllSyntaxBinCompat8
extends PartialNextSyntax
with NextSyntax
with PartialPreviousSyntax
with PreviousSyntax
with BoundedEnumerableSyntax
78 changes: 78 additions & 0 deletions core/src/main/scala/cats/syntax/enumerable.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2015 Typelevel
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package cats
package syntax

import cats.kernel._

trait PartialNextSyntax {
implicit final def catsSyntaxPartialNext[A](a: A): PartialNextOps[A] =
new PartialNextOps(a)
}

final class PartialNextOps[A](private val lhs: A) extends AnyVal {
def partialNext(implicit A: PartialNext[A]): Option[A] =
A.partialNext(lhs)
}

trait NextSyntax extends PartialNextSyntax {
implicit final def catsSyntaxNext[A](a: A): NextOps[A] =
new NextOps(a)
}

final class NextOps[A](private val lhs: A) extends AnyVal {
def next(implicit A: Next[A]): A =
A.next(lhs)
}

trait PartialPreviousSyntax {
implicit final def catsSyntaxPartialPrevious[A](a: A): PartialPreviousOps[A] =
new PartialPreviousOps(a)
}

final class PartialPreviousOps[A](private val lhs: A) extends AnyVal {
def partialPrevious(implicit A: PartialPrevious[A]): Option[A] =
A.partialPrevious(lhs)
}

trait PreviousSyntax extends PartialPreviousSyntax {
implicit final def catsSyntaxPrevious[A](a: A): PreviousOps[A] =
new PreviousOps(a)
}

final class PreviousOps[A](private val lhs: A) extends AnyVal {
def previous(implicit A: Previous[A]): A =
A.previous(lhs)
}

trait BoundedEnumerableSyntax extends NextSyntax with PreviousSyntax {
implicit final def catsSyntaxForBoundedEnumerable[A](a: A): BoundedEnumerableOps[A] =
new BoundedEnumerableOps(a)
}

final class BoundedEnumerableOps[A](private val lhs: A) extends AnyVal {
def cycleNext(implicit A0: PartialNext[A], A1: LowerBounded[A]): A =
A0.partialNext(lhs).getOrElse(A1.minBound)

def cyclePrevious(implicit A0: PartialPrevious[A], A1: UpperBounded[A]): A =
A0.partialPrevious(lhs).getOrElse(A1.maxBound)
}
66 changes: 66 additions & 0 deletions kernel/src/main/scala/cats/kernel/Enumerable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@ trait PartialNext[@sp A] {
def partialNext(a: A): Option[A]
}

object PartialNext {

def apply[A](implicit A: PartialNext[A]): PartialNext[A] =
A

implicit def catsKernelPartialNextForUnit: PartialNext[Unit] =
cats.kernel.instances.unit.catsKernelStdOrderForUnit
implicit def catsKernelPartialNextForBoolean: PartialNext[Boolean] =
cats.kernel.instances.boolean.catsKernelStdOrderForBoolean
implicit def catsKernelPartialNextForByte: PartialNext[Byte] =
cats.kernel.instances.byte.catsKernelStdOrderForByte
implicit def catsKernelPartialNextForInt: PartialNext[Int] =
cats.kernel.instances.int.catsKernelStdOrderForInt
implicit def catsKernelPartialNextForShort: PartialNext[Short] =
cats.kernel.instances.short.catsKernelStdOrderForShort
implicit def catsKernelPartialNextForLong: PartialNext[Long] =
cats.kernel.instances.long.catsKernelStdOrderForLong
implicit def catsKernelPartialNextForChar: PartialNext[Char] =
cats.kernel.instances.char.catsKernelStdOrderForChar
implicit def catsKernelPartialNextForBigInt: PartialNext[BigInt] =
cats.kernel.instances.bigInt.catsKernelStdOrderForBigInt
}

/**
* A typeclass with an operation which returns a member which is
* always greater than the one supplied.
Expand All @@ -42,6 +65,14 @@ trait Next[@sp A] extends PartialNext[A] {
override def partialNext(a: A): Option[A] = Some(next(a))
}

object Next {
def apply[A](implicit A: Next[A]): Next[A] =
A

implicit def catsKernelNextForBigInt: Next[BigInt] =
cats.kernel.instances.bigInt.catsKernelStdOrderForBigInt
}

/**
* A typeclass with an operation which returns a member which is
* smaller or `None` than the one supplied.
Expand All @@ -51,6 +82,28 @@ trait PartialPrevious[@sp A] {
def partialPrevious(a: A): Option[A]
}

object PartialPrevious {
def apply[A](implicit A: PartialPrevious[A]): PartialPrevious[A] =
A

implicit def catsKernelPartialPreviousForUnit: PartialPrevious[Unit] =
cats.kernel.instances.unit.catsKernelStdOrderForUnit
implicit def catsKernelPartialPreviousForBoolean: PartialPrevious[Boolean] =
cats.kernel.instances.boolean.catsKernelStdOrderForBoolean
implicit def catsKernelPartialPreviousForByte: PartialPrevious[Byte] =
cats.kernel.instances.byte.catsKernelStdOrderForByte
implicit def catsKernelPartialPreviousForInt: PartialPrevious[Int] =
cats.kernel.instances.int.catsKernelStdOrderForInt
implicit def catsKernelPartialPreviousForShort: PartialPrevious[Short] =
cats.kernel.instances.short.catsKernelStdOrderForShort
implicit def catsKernelPartialPreviousForLong: PartialPrevious[Long] =
cats.kernel.instances.long.catsKernelStdOrderForLong
implicit def catsKernelPartialPreviousForChar: PartialPrevious[Char] =
cats.kernel.instances.char.catsKernelStdOrderForChar
implicit def catsKernelPartialPreviousForBigInt: PartialPrevious[BigInt] =
cats.kernel.instances.bigInt.catsKernelStdOrderForBigInt
}

/**
* A typeclass with an operation which returns a member which is
* always smaller than the one supplied.
Expand All @@ -61,6 +114,14 @@ trait Previous[@sp A] extends PartialPrevious[A] {
override def partialPrevious(a: A): Option[A] = Some(previous(a))
}

object Previous {
def apply[A](implicit A: Previous[A]): Previous[A] =
A

implicit def catsKernelPreviousForBigInt: Previous[BigInt] =
cats.kernel.instances.bigInt.catsKernelStdOrderForBigInt
}

/**
* A typeclass which has both `previous` and `next` operations
* such that `next . previous == identity`.
Expand All @@ -70,6 +131,11 @@ trait UnboundedEnumerable[@sp A] extends Next[A] with Previous[A] {
override def partialOrder: PartialOrder[A] = order
}

object UnboundedEnumerable {
def apply[A](implicit A: UnboundedEnumerable[A]): UnboundedEnumerable[A] =
A
}

trait BoundedEnumerable[@sp A] extends PartialPreviousUpperBounded[A] with PartialNextLowerBounded[A] {

def order: Order[A]
Expand Down

0 comments on commit 4b0a87b

Please sign in to comment.