Skip to content

Commit 9e6fb7b

Browse files
committed
add NeAlt-ve s12ns for monad transformers
1 parent 9b5d664 commit 9e6fb7b

13 files changed

+294
-17
lines changed

Diff for: core/src/main/scala-2.13+/cats/data/ZipLazyList.scala

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ object ZipLazyList {
4545

4646
def combineK[A](x: ZipLazyList[A], y: ZipLazyList[A]): ZipLazyList[A] =
4747
ZipLazyList(cats.instances.lazyList.catsStdInstancesForLazyList.combineK(x.value, y.value))
48+
49+
override def prependK[A](a: A, fa: ZipLazyList[A]): ZipLazyList[A] =
50+
ZipLazyList(cats.instances.lazyList.catsStdInstancesForLazyList.prependK(a, fa.value))
51+
52+
override def appendK[A](fa: ZipLazyList[A], a: A): ZipLazyList[A] =
53+
ZipLazyList(cats.instances.lazyList.catsStdInstancesForLazyList.appendK(fa.value, a))
4854
}
4955

5056
implicit def catsDataEqForZipLazyList[A: Eq]: Eq[ZipLazyList[A]] =

Diff for: core/src/main/scala-2.13+/cats/data/ZipStream.scala

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ object ZipStream {
4747

4848
def combineK[A](x: ZipStream[A], y: ZipStream[A]): ZipStream[A] =
4949
ZipStream(cats.instances.stream.catsStdInstancesForStream.combineK(x.value, y.value))
50+
51+
override def prependK[A](a: A, fa: ZipStream[A]): ZipStream[A] =
52+
ZipStream(cats.instances.stream.catsStdInstancesForStream.prependK(a, fa.value))
53+
54+
override def appendK[A](fa: ZipStream[A], a: A): ZipStream[A] =
55+
ZipStream(cats.instances.stream.catsStdInstancesForStream.appendK(fa.value, a))
5056
}
5157

5258
implicit def catsDataEqForZipStream[A: Eq]: Eq[ZipStream[A]] =

Diff for: core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala

+71-6
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,17 @@ sealed abstract private[data] class IRWSTInstances1 extends IRWSTInstances2 {
668668
}
669669

670670
sealed abstract private[data] class IRWSTInstances2 extends IRWSTInstances3 {
671+
implicit def catsDataNonEmptyAlternativeForIRWST[F[_], E, L, S](implicit
672+
FM: Monad[F],
673+
FA: NonEmptyAlternative[F],
674+
L0: Monoid[L]
675+
): NonEmptyAlternative[IndexedReaderWriterStateT[F, E, L, S, S, *]] =
676+
new RWSTNonEmptyAlternative[F, E, L, S] {
677+
implicit def G: NonEmptyAlternative[F] = FA
678+
implicit def F: Monad[F] = FM
679+
implicit def L: Monoid[L] = L0
680+
}
681+
671682
implicit def catsDataAlternativeForIRWST[F[_], E, L, S](implicit
672683
FM: Monad[F],
673684
FA: Alternative[F],
@@ -789,6 +800,10 @@ sealed abstract private[data] class RWSTMonad[F[_], E, L, S]
789800

790801
sealed abstract private[data] class IRWSTSemigroupK[F[_], E, L, SA, SB] extends IRWSTSemigroupK1[F, E, L, SA, SB]
791802

803+
sealed abstract private[data] class RWSTNonEmptyAlternative[F[_], E, L, S]
804+
extends IRWSTFunctor[F, E, L, S, S]
805+
with RWSTNonEmptyAlternative1[F, E, L, S]
806+
792807
sealed abstract private[data] class RWSTAlternative[F[_], E, L, S]
793808
extends IRWSTFunctor[F, E, L, S, S]
794809
with RWSTAlternative1[F, E, L, S]
@@ -821,8 +836,54 @@ private trait IRWSTSemigroupK1[F[_], E, L, SA, SB] extends SemigroupK[IndexedRea
821836
}
822837
}
823838

824-
private trait RWSTAlternative1[F[_], E, L, S]
839+
private trait RWSTNonEmptyAlternative1[F[_], E, L, S]
825840
extends IRWSTSemigroupK1[F, E, L, S, S]
841+
with NonEmptyAlternative[ReaderWriterStateT[F, E, L, S, *]] {
842+
843+
implicit def F: Monad[F]
844+
def G: NonEmptyAlternative[F]
845+
implicit def L: Monoid[L]
846+
847+
// Enforces binary compatibility for RWSTAlternative1 between 2.6.1 and newer versions.
848+
final protected def pure0[A](a: A): ReaderWriterStateT[F, E, L, S, A] =
849+
ReaderWriterStateT.pure[F, E, L, S, A](a)
850+
851+
// Enforces binary compatibility for RWSTAlternative1 between 2.6.1 and newer versions.
852+
final protected def ap0[A, B](
853+
ff: ReaderWriterStateT[F, E, L, S, A => B]
854+
)(
855+
fa: ReaderWriterStateT[F, E, L, S, A]
856+
): ReaderWriterStateT[F, E, L, S, B] =
857+
ff.flatMap(f => fa.map(f)(F))(F, L)
858+
859+
def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = pure0(a)
860+
861+
def ap[A, B](
862+
ff: ReaderWriterStateT[F, E, L, S, A => B]
863+
)(
864+
fa: ReaderWriterStateT[F, E, L, S, A]
865+
): ReaderWriterStateT[F, E, L, S, B] =
866+
ap0(ff)(fa)
867+
868+
override def prependK[A](
869+
a: A,
870+
fa: IndexedReaderWriterStateT[F, E, L, S, S, A]
871+
): IndexedReaderWriterStateT[F, E, L, S, S, A] =
872+
IndexedReaderWriterStateT { (e, s) =>
873+
G.prependK((L.empty, s, a), fa.run(e, s))
874+
}
875+
876+
override def appendK[A](
877+
fa: IndexedReaderWriterStateT[F, E, L, S, S, A],
878+
a: A
879+
): IndexedReaderWriterStateT[F, E, L, S, S, A] =
880+
IndexedReaderWriterStateT { (e, s) =>
881+
G.appendK(fa.run(e, s), (L.empty, s, a))
882+
}
883+
}
884+
885+
private trait RWSTAlternative1[F[_], E, L, S]
886+
extends RWSTNonEmptyAlternative1[F, E, L, S]
826887
with Alternative[ReaderWriterStateT[F, E, L, S, *]] {
827888

828889
implicit def F: Monad[F]
@@ -831,11 +892,15 @@ private trait RWSTAlternative1[F[_], E, L, S]
831892

832893
def empty[A]: ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.liftF(G.empty[A])
833894

834-
def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.pure[F, E, L, S, A](a)
895+
// Must exist in this trait for binary compatibility.
896+
override def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] =
897+
pure0(a)
835898

836-
def ap[A, B](
899+
// Must exist in this trait for binary compatibility.
900+
override def ap[A, B](
837901
ff: ReaderWriterStateT[F, E, L, S, A => B]
838-
)(fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, B] =
839-
ff.flatMap(f => fa.map(f)(F))(F, L)
840-
902+
)(
903+
fa: ReaderWriterStateT[F, E, L, S, A]
904+
): ReaderWriterStateT[F, E, L, S, B] =
905+
ap0(ff)(fa)
841906
}

Diff for: core/src/main/scala/cats/data/IndexedStateT.scala

+25-5
Original file line numberDiff line numberDiff line change
@@ -299,19 +299,25 @@ sealed abstract private[data] class IndexedStateTInstances extends IndexedStateT
299299
}
300300

301301
sealed abstract private[data] class IndexedStateTInstances1 extends IndexedStateTInstances2 {
302+
implicit def catsDataNonEmptyAlternativeForIndexedStateT[F[_], S](implicit
303+
FM: Monad[F],
304+
FA: NonEmptyAlternative[F]
305+
): NonEmptyAlternative[IndexedStateT[F, S, S, *]] with Monad[IndexedStateT[F, S, S, *]] =
306+
new IndexedStateTNonEmptyAlternative[F, S] { implicit def F = FM; implicit def G = FA }
307+
302308
implicit def catsDataMonadErrorForIndexedStateT[F[_], S, E](implicit
303309
F0: MonadError[F, E]
304310
): MonadError[IndexedStateT[F, S, S, *], E] =
305311
new IndexedStateTMonadError[F, S, E] { implicit def F = F0 }
312+
}
306313

314+
sealed abstract private[data] class IndexedStateTInstances2 extends IndexedStateTInstances3 {
307315
implicit def catsDataSemigroupKForIndexedStateT[F[_], SA, SB](implicit
308316
F0: Monad[F],
309317
G0: SemigroupK[F]
310318
): SemigroupK[IndexedStateT[F, SA, SB, *]] =
311319
new IndexedStateTSemigroupK[F, SA, SB] { implicit def F = F0; implicit def G = G0 }
312-
}
313320

314-
sealed abstract private[data] class IndexedStateTInstances2 extends IndexedStateTInstances3 {
315321
implicit def catsDataMonadForIndexedStateT[F[_], S](implicit F0: Monad[F]): Monad[IndexedStateT[F, S, S, *]] =
316322
new IndexedStateTMonad[F, S] { implicit def F = F0 }
317323
}
@@ -507,14 +513,28 @@ sealed abstract private[data] class IndexedStateTContravariantMonoidal[F[_], S]
507513
)
508514
}
509515

510-
sealed abstract private[data] class IndexedStateTAlternative[F[_], S]
516+
sealed abstract private[data] class IndexedStateTNonEmptyAlternative[F[_], S]
511517
extends IndexedStateTMonad[F, S]
512-
with Alternative[IndexedStateT[F, S, S, *]] {
513-
def G: Alternative[F]
518+
with NonEmptyAlternative[IndexedStateT[F, S, S, *]] {
519+
520+
def G: NonEmptyAlternative[F]
514521

515522
def combineK[A](x: IndexedStateT[F, S, S, A], y: IndexedStateT[F, S, S, A]): IndexedStateT[F, S, S, A] =
516523
IndexedStateT[F, S, S, A](s => G.combineK(x.run(s), y.run(s)))(G)
517524

525+
override def prependK[A](a: A, fa: IndexedStateT[F, S, S, A]): IndexedStateT[F, S, S, A] =
526+
IndexedStateT[F, S, S, A](s => G.prependK((s, a), fa.run(s)))(G)
527+
528+
override def appendK[A](fa: IndexedStateT[F, S, S, A], a: A): IndexedStateT[F, S, S, A] =
529+
IndexedStateT[F, S, S, A](s => G.appendK(fa.run(s), (s, a)))(G)
530+
}
531+
532+
sealed abstract private[data] class IndexedStateTAlternative[F[_], S]
533+
extends IndexedStateTNonEmptyAlternative[F, S]
534+
with Alternative[IndexedStateT[F, S, S, *]] {
535+
536+
def G: Alternative[F]
537+
518538
def empty[A]: IndexedStateT[F, S, S, A] =
519539
IndexedStateT.liftF[F, S, A](G.empty[A])(G)
520540
}

Diff for: core/src/main/scala/cats/data/Kleisli.scala

+19-1
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,11 @@ sealed abstract private[data] class KleisliInstances2 extends KleisliInstances3
460460
}
461461

462462
sealed abstract private[data] class KleisliInstances3 extends KleisliInstances4 {
463+
implicit def catsDataNonEmptyAlternativeForKleisli[F[_], A](implicit
464+
F0: NonEmptyAlternative[F]
465+
): NonEmptyAlternative[Kleisli[F, A, *]] =
466+
new KleisliNonEmptyAlternative[F, A] { def F: NonEmptyAlternative[F] = F0 }
467+
463468
implicit def catsDataMonoidKForKleisli[F[_], A](implicit F0: MonoidK[F]): MonoidK[Kleisli[F, A, *]] =
464469
new KleisliMonoidK[F, A] { def F: MonoidK[F] = F0 }
465470

@@ -614,9 +619,22 @@ sealed private[data] trait KleisliMonoidK[F[_], A] extends MonoidK[Kleisli[F, A,
614619
override def empty[B]: Kleisli[F, A, B] = Kleisli.liftF(F.empty[B])
615620
}
616621

622+
private[data] trait KleisliNonEmptyAlternative[F[_], A]
623+
extends NonEmptyAlternative[Kleisli[F, A, *]]
624+
with KleisliApplicative[F, A]
625+
with KleisliSemigroupK[F, A] {
626+
implicit def F: NonEmptyAlternative[F]
627+
628+
override def prependK[B](b: B, fa: Kleisli[F, A, B]): Kleisli[F, A, B] =
629+
Kleisli(a => F.prependK(b, fa.run(a)))
630+
631+
override def appendK[B](fa: Kleisli[F, A, B], b: B): Kleisli[F, A, B] =
632+
Kleisli(a => F.appendK(fa.run(a), b))
633+
}
634+
617635
private[data] trait KleisliAlternative[F[_], A]
618636
extends Alternative[Kleisli[F, A, *]]
619-
with KleisliApplicative[F, A]
637+
with KleisliNonEmptyAlternative[F, A]
620638
with KleisliMonoidK[F, A] {
621639
implicit def F: Alternative[F]
622640
}

Diff for: core/src/main/scala/cats/data/Nested.scala

+20-1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ sealed abstract private[data] class NestedInstances3 extends NestedInstances4 {
170170
}
171171

172172
sealed abstract private[data] class NestedInstances4 extends NestedInstances5 {
173+
implicit def catsDataNonEmptyAlternativeForNested[F[_]: NonEmptyAlternative, G[_]: Applicative]
174+
: NonEmptyAlternative[Nested[F, G, *]] =
175+
new NestedNonEmptyAlternative[F, G] {
176+
val FG: NonEmptyAlternative[λ[α => F[G[α]]]] = NonEmptyAlternative[F].compose[G]
177+
}
178+
173179
implicit def catsDataApplicativeErrorForNested[F[_], G[_], E](implicit
174180
F: ApplicativeError[F, E],
175181
G0: Applicative[G]
@@ -322,9 +328,22 @@ private[data] trait NestedMonoidK[F[_], G[_]] extends MonoidK[Nested[F, G, *]] w
322328
def empty[A]: Nested[F, G, A] = Nested(FG.empty[A])
323329
}
324330

331+
private[data] trait NestedNonEmptyAlternative[F[_], G[_]]
332+
extends NonEmptyAlternative[Nested[F, G, *]]
333+
with NestedApplicative[F, G]
334+
with NestedSemigroupK[F, G] {
335+
def FG: NonEmptyAlternative[λ[α => F[G[α]]]]
336+
337+
override def prependK[A](a: A, fa: Nested[F, G, A]): Nested[F, G, A] =
338+
Nested(FG.prependK(a, fa.value))
339+
340+
override def appendK[A](fa: Nested[F, G, A], a: A): Nested[F, G, A] =
341+
Nested(FG.appendK(fa.value, a))
342+
}
343+
325344
private[data] trait NestedAlternative[F[_], G[_]]
326345
extends Alternative[Nested[F, G, *]]
327-
with NestedApplicative[F, G]
346+
with NestedNonEmptyAlternative[F, G]
328347
with NestedMonoidK[F, G] {
329348
def FG: Alternative[λ[α => F[G[α]]]]
330349
}

Diff for: core/src/main/scala/cats/data/Tuple2K.scala

+24-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ sealed abstract private[data] class Tuple2KInstances1 extends Tuple2KInstances2
126126
def F: Alternative[F] = FF
127127
def G: Alternative[G] = GG
128128
}
129+
129130
implicit def catsDataFoldableForTuple2K[F[_], G[_]](implicit
130131
FF: Foldable[F],
131132
GF: Foldable[G]
@@ -175,6 +176,14 @@ sealed abstract private[data] class Tuple2KInstances2 extends Tuple2KInstances3
175176
def F: MonoidK[F] = FF
176177
def G: MonoidK[G] = GG
177178
}
179+
implicit def catsDataNonEmptyAlternativeForTuple2K[F[_], G[_]](implicit
180+
FF: NonEmptyAlternative[F],
181+
GG: NonEmptyAlternative[G]
182+
): NonEmptyAlternative[λ[α => Tuple2K[F, G, α]]] =
183+
new Tuple2KNonEmptyAlternative[F, G] {
184+
def F: NonEmptyAlternative[F] = FF
185+
def G: NonEmptyAlternative[G] = GG
186+
}
178187
}
179188

180189
sealed abstract private[data] class Tuple2KInstances3 extends Tuple2KInstances4 {
@@ -352,9 +361,23 @@ sealed private[data] trait Tuple2KMonoidK[F[_], G[_]]
352361
Tuple2K(F.empty[A], G.empty[A])
353362
}
354363

364+
sealed private[data] trait Tuple2KNonEmptyAlternative[F[_], G[_]]
365+
extends NonEmptyAlternative[λ[α => Tuple2K[F, G, α]]]
366+
with Tuple2KApplicative[F, G]
367+
with Tuple2KSemigroupK[F, G] {
368+
def F: NonEmptyAlternative[F]
369+
def G: NonEmptyAlternative[G]
370+
371+
override def prependK[A](a: A, fa: Tuple2K[F, G, A]): Tuple2K[F, G, A] =
372+
Tuple2K(F.prependK(a, fa.first), G.prependK(a, fa.second))
373+
374+
override def appendK[A](fa: Tuple2K[F, G, A], a: A): Tuple2K[F, G, A] =
375+
Tuple2K(F.appendK(fa.first, a), G.appendK(fa.second, a))
376+
}
377+
355378
sealed private[data] trait Tuple2KAlternative[F[_], G[_]]
356379
extends Alternative[λ[α => Tuple2K[F, G, α]]]
357-
with Tuple2KApplicative[F, G]
380+
with Tuple2KNonEmptyAlternative[F, G]
358381
with Tuple2KMonoidK[F, G] {
359382
def F: Alternative[F]
360383
def G: Alternative[G]

Diff for: core/src/main/scala/cats/data/WriterT.scala

+24-2
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,15 @@ sealed abstract private[data] class WriterTInstances8 extends WriterTInstances9
535535
}
536536

537537
sealed abstract private[data] class WriterTInstances9 extends WriterTInstances10 {
538+
implicit def catsDataNonEmptyAlternativeForWriterT[F[_], L](implicit
539+
F: NonEmptyAlternative[F],
540+
L: Monoid[L]
541+
): NonEmptyAlternative[WriterT[F, L, *]] =
542+
new WriterTNonEmptyAlternative[F, L] {
543+
implicit val F0: NonEmptyAlternative[F] = F
544+
implicit val L0: Monoid[L] = L
545+
}
546+
538547
implicit def catsDataMonoidKForWriterT[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, *]] =
539548
new WriterTMonoidK[F, L] {
540549
implicit val F0: MonoidK[F] = F
@@ -739,10 +748,23 @@ sealed private[data] trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L,
739748
def empty[A]: WriterT[F, L, A] = WriterT(F0.empty)
740749
}
741750

751+
sealed private[data] trait WriterTNonEmptyAlternative[F[_], L]
752+
extends NonEmptyAlternative[WriterT[F, L, *]]
753+
with WriterTSemigroupK[F, L]
754+
with WriterTApplicative[F, L] {
755+
implicit override def F0: NonEmptyAlternative[F]
756+
757+
override def prependK[A](a: A, fa: WriterT[F, L, A]): WriterT[F, L, A] =
758+
WriterT(F0.prependK((L0.empty, a), fa.run))
759+
760+
override def appendK[A](fa: WriterT[F, L, A], a: A): WriterT[F, L, A] =
761+
WriterT(F0.appendK(fa.run, (L0.empty, a)))
762+
}
763+
742764
sealed private[data] trait WriterTAlternative[F[_], L]
743765
extends Alternative[WriterT[F, L, *]]
744-
with WriterTMonoidK[F, L]
745-
with WriterTApplicative[F, L] {
766+
with WriterTNonEmptyAlternative[F, L]
767+
with WriterTMonoidK[F, L] {
746768
implicit override def F0: Alternative[F]
747769
}
748770

Diff for: tests/shared/src/test/scala/cats/tests/IndexedStateTSuite.scala

+26
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,31 @@ class IndexedStateTSuite extends CatsSuite {
509509
)
510510
}
511511

512+
{
513+
// F has an NonEmptyAlternative
514+
implicit val G: Monad[ListWrapper] = ListWrapper.monad
515+
implicit val F: NonEmptyAlternative[ListWrapper] = ListWrapper.nonEmptyAlternative
516+
val SA =
517+
IndexedStateT
518+
.catsDataNonEmptyAlternativeForIndexedStateT[ListWrapper, MiniInt](ListWrapper.monad, ListWrapper.alternative)
519+
520+
implicit val f: Isomorphisms[IndexedStateT[ListWrapper, MiniInt, MiniInt, *]] = Isomorphisms.invariant(SA)
521+
522+
checkAll(
523+
"IndexedStateT[ListWrapper, MiniInt, Int, Int]",
524+
NonEmptyAlternativeTests[IndexedStateT[ListWrapper, MiniInt, MiniInt, *]](SA).nonEmptyAlternative[Int, Int, Int]
525+
)
526+
checkAll("Alternative[IndexedStateT[ListWrapper, Int, Int, *]]", SerializableTests.serializable(SA))
527+
528+
Monad[IndexedStateT[ListWrapper, Int, Int, *]]
529+
FlatMap[IndexedStateT[ListWrapper, Int, Int, *]]
530+
NonEmptyAlternative[IndexedStateT[ListWrapper, Int, Int, *]]
531+
Applicative[IndexedStateT[ListWrapper, Int, Int, *]]
532+
Apply[IndexedStateT[ListWrapper, Int, Int, *]]
533+
// Functor[IndexedStateT[ListWrapper, Int, Int, *]]
534+
SemigroupK[IndexedStateT[ListWrapper, Int, Int, *]]
535+
}
536+
512537
{
513538
// F has an Alternative
514539
implicit val G: Monad[ListWrapper] = ListWrapper.monad
@@ -526,6 +551,7 @@ class IndexedStateTSuite extends CatsSuite {
526551

527552
Monad[IndexedStateT[ListWrapper, Int, Int, *]]
528553
FlatMap[IndexedStateT[ListWrapper, Int, Int, *]]
554+
NonEmptyAlternative[IndexedStateT[ListWrapper, Int, Int, *]]
529555
Alternative[IndexedStateT[ListWrapper, Int, Int, *]]
530556
Applicative[IndexedStateT[ListWrapper, Int, Int, *]]
531557
Apply[IndexedStateT[ListWrapper, Int, Int, *]]

0 commit comments

Comments
 (0)