Skip to content

Commit

Permalink
move prependK/appendK to NonEmptyAlternative
Browse files Browse the repository at this point in the history
  • Loading branch information
satorg committed Nov 3, 2021
1 parent 53d7eb2 commit fb591ce
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 62 deletions.
28 changes: 1 addition & 27 deletions core/src/main/scala/cats/Alternative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,6 @@ import scala.annotation.implicitNotFound
def guard(condition: Boolean): F[Unit] =
if (condition) unit else empty

/**
* Lift `a` into `F[_]` and prepend it to `fa`.
*
* Example:
* {{{
* scala> Alternative[List].prependK(1, List(2, 3, 4))
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def prependK[A](a: A, fa: F[A]): F[A] = combineK(pure(a), fa)

/**
* Lift `a` into `F[_]` and append it to `fa`.
*
* Example:
* {{{
* scala> Alternative[List].appendK(List(1, 2, 3), 4)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def appendK[A](fa: F[A], a: A): F[A] = combineK(fa, pure(a))

override def compose[G[_]: Applicative]: Alternative[λ[α => F[G[α]]]] =
new ComposedAlternative[F, G] {
val F = self
Expand Down Expand Up @@ -142,11 +120,8 @@ object Alternative {
typeClassInstance.separate[G, B, C](self.asInstanceOf[F[G[B, C]]])(FM, G)
def separateFoldable[G[_, _], B, C](implicit ev$1: A <:< G[B, C], G: Bifoldable[G], FF: Foldable[F]): (F[B], F[C]) =
typeClassInstance.separateFoldable[G, B, C](self.asInstanceOf[F[G[B, C]]])(G, FF)
// Note: `prependK` is added manually since simulacrum was not able to handle `self` as a second parameter.
def prependK(a: A): F[A] = typeClassInstance.prependK[A](a, self)
def appendK(a: A): F[A] = typeClassInstance.appendK[A](self, a)
}
trait AllOps[F[_], A] extends Ops[F, A] with Applicative.AllOps[F, A] with MonoidK.AllOps[F, A] {
trait AllOps[F[_], A] extends Ops[F, A] with NonEmptyAlternative.AllOps[F, A] with MonoidK.AllOps[F, A] {
type TypeClassType <: Alternative[F]
}
trait ToAlternativeOps extends Serializable {
Expand All @@ -164,5 +139,4 @@ object Alternative {
/* ======================================================================== */
/* END OF SIMULACRUM-MANAGED CODE */
/* ======================================================================== */

}
26 changes: 26 additions & 0 deletions core/src/main/scala/cats/NonEmptyAlternative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ import scala.annotation.implicitNotFound

@implicitNotFound("Could not find an instance of NonEmptyAlternative for ${F}")
@typeclass trait NonEmptyAlternative[F[_]] extends Applicative[F] with SemigroupK[F] { self =>

/**
* Lift `a` into `F[_]` and prepend it to `fa`.
*
* Example:
* {{{
* scala> NonEmptyAlternative[List].prependK(1, List(2, 3, 4))
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def prependK[A](a: A, fa: F[A]): F[A] = combineK(pure(a), fa)

/**
* Lift `a` into `F[_]` and append it to `fa`.
*
* Example:
* {{{
* scala> NonEmptyAlternative[List].appendK(List(1, 2, 3), 4)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def appendK[A](fa: F[A], a: A): F[A] = combineK(fa, pure(a))

override def compose[G[_]: Applicative]: NonEmptyAlternative[λ[α => F[G[α]]]] =
new ComposedNonEmptyAlternative[F, G] {
val F = self
Expand Down Expand Up @@ -36,6 +59,9 @@ object NonEmptyAlternative {
type TypeClassType <: NonEmptyAlternative[F]
def self: F[A]
val typeClassInstance: TypeClassType
// Note: `prependK` has to be added manually since simulacrum is not able to handle `self` as a second parameter.
// def prependK(a: A): F[A] = typeClassInstance.prependK[A](a, self)
def appendK(a: A): F[A] = typeClassInstance.appendK[A](self, a)
}
trait AllOps[F[_], A] extends Ops[F, A] with Applicative.AllOps[F, A] with SemigroupK.AllOps[F, A] {
type TypeClassType <: NonEmptyAlternative[F]
Expand Down
32 changes: 0 additions & 32 deletions core/src/main/scala/cats/syntax/alternative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ trait AlternativeSyntax {

implicit final def catsSyntaxAlternativeGuard(b: Boolean): GuardOps =
new GuardOps(b)

implicit final def catsSyntaxAlternativeCombine[F[_], A](fa: F[A]): CombineOps[F, A] =
new CombineOps(fa)
}

final class UniteOps[F[_], G[_], A](private val fga: F[G[A]]) extends AnyVal {
Expand Down Expand Up @@ -79,32 +76,3 @@ final class GuardOps(private val condition: Boolean) extends AnyVal {
*/
def guard[F[_]](implicit F: Alternative[F]): F[Unit] = F.guard(condition)
}

final class CombineOps[F[_], A](private val fa: F[A]) extends AnyVal {

/**
* @see [[Alternative.prependK]]
*
* Example:
* {{{
* scala> import cats.syntax.all._
*
* scala> List(2, 3, 4).prependK(1)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def prependK(a: A)(implicit F: Alternative[F]): F[A] = F.prependK(a, fa)

/**
* @see [[Alternative.appendK]]
*
* Example:
* {{{
* scala> import cats.syntax.all._
*
* scala> List(1, 2, 3).appendK(4)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def appendK(a: A)(implicit F: Alternative[F]): F[A] = F.appendK(fa, a)
}
37 changes: 35 additions & 2 deletions core/src/main/scala/cats/syntax/nonEmptyAlternative.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
package cats.syntax
package cats
package syntax

trait NonEmptyAlternativeSyntax {}
trait NonEmptyAlternativeSyntax {
implicit final def catsSyntaxNonEmptyAlternative[F[_], A](fa: F[A]): NonEmptyAlternativeOps[F, A] =
new NonEmptyAlternativeOps(fa)
}

final class NonEmptyAlternativeOps[F[_], A](private val fa: F[A]) extends AnyVal {

/**
* @see [[NonEmptyAlternative.prependK]]
*
* Example:
* {{{
* scala> import cats.syntax.all._
*
* scala> List(2, 3, 4).prependK(1)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def prependK(a: A)(implicit F: NonEmptyAlternative[F]): F[A] = F.prependK(a, fa)

/**
* @see [[NonEmptyAlternative.appendK]]
*
* Example:
* {{{
* scala> import cats.syntax.all._
*
* scala> List(1, 2, 3).appendK(4)
* res0: List[Int] = List(1, 2, 3, 4)
* }}}
*/
def appendK(a: A)(implicit F: NonEmptyAlternative[F]): F[A] = F.appendK(fa, a)
}
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ object SyntaxSuite {
val gfab2 = fgab.leftSequence
}

def testAlternative[F[_]: Alternative, A]: Unit = {
def testNonEmptyAlternative[F[_]: NonEmptyAlternative, A]: Unit = {
val fa = mock[F[A]]
val a = mock[A]

Expand Down

0 comments on commit fb591ce

Please sign in to comment.