Skip to content

Commit

Permalink
added CommutativeMonad instances for Kleisli and WriterT
Browse files Browse the repository at this point in the history
  • Loading branch information
kailuowang committed Jul 17, 2017
1 parent bc0f309 commit c5ab4a5
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
18 changes: 12 additions & 6 deletions core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ private[data] sealed trait KleisliFunctions {
}

private[data] sealed abstract class KleisliInstances extends KleisliInstances0 {
implicit def catsDataCommutativeMonadForKleisli[F[_], A, B](implicit F0: CommutativeMonad[F]): CommutativeMonad[Kleisli[F, A, ?]] =
new KleisliMonad[F, A] with CommutativeMonad[Kleisli[F, A, ?]] {
implicit def F: Monad[F] = F0
}
}

private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 {
implicit def catsDataMonoidForKleisli[F[_], A, B](implicit FB0: Monoid[F[B]]): Monoid[Kleisli[F, A, B]] =
new KleisliMonoid[F, A, B] { def FB: Monoid[F[B]] = FB0 }

Expand Down Expand Up @@ -115,20 +121,20 @@ private[data] sealed abstract class KleisliInstances extends KleisliInstances0 {
new KleisliApplicativeError[F, A, E] { def F: ApplicativeError[F, E] = AE }
}

private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 {
private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 {
implicit def catsDataArrowForKleisli[F[_]](implicit M: Monad[F]): Arrow[Kleisli[F, ?, ?]] =
new KleisliArrow[F] { def F: Monad[F] = M }

implicit def catsDataMonadErrorForKleisli[F[_], A, E](implicit ME: MonadError[F, E]): MonadError[Kleisli[F, A, ?], E] =
new KleisliMonadError[F, A, E] { def F: MonadError[F, E] = ME }
}

private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 {
private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 {
implicit def catsDataMonadReaderForKleisli[F[_], A](implicit M: Monad[F]): MonadReader[Kleisli[F, A, ?], A] =
new KleisliMonadReader[F, A] { def F: Monad[F] = M }
}

private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 {
private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 {
implicit def catsDataChoiceForKleisli[F[_]](implicit M: Monad[F]): Choice[Kleisli[F, ?, ?]] =
new KleisliChoice[F] { def F: Monad[F] = M }

Expand All @@ -151,17 +157,17 @@ private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3
Compose[Kleisli[F, ?, ?]].algebraK
}

private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 {
private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 {
implicit def catsDataApplicativeForKleisli[F[_], A](implicit A: Applicative[F]): Applicative[Kleisli[F, A, ?]] =
new KleisliApplicative[F, A] { def F: Applicative[F] = A }
}

private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 {
private[data] sealed abstract class KleisliInstances5 extends KleisliInstances6 {
implicit def catsDataApplyForKleisli[F[_], A](implicit A: Apply[F]): Apply[Kleisli[F, A, ?]] =
new KleisliApply[F, A] { def F: Apply[F] = A }
}

private[data] sealed abstract class KleisliInstances5 {
private[data] sealed abstract class KleisliInstances6 {
implicit def catsDataFunctorForKleisli[F[_], A](implicit F0: Functor[F]): Functor[Kleisli[F, A, ?]] =
new KleisliFunctor[F, A] { def F: Functor[F] = F0 }
}
Expand Down
31 changes: 20 additions & 11 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package data

import cats.kernel.instances.tuple._
import cats.functor.{Bifunctor, Contravariant}
import cats.kernel.CommutativeMonoid
import cats.syntax.semigroup._

final case class WriterT[F[_], L, V](run: F[(L, V)]) {
Expand Down Expand Up @@ -66,6 +67,14 @@ object WriterT extends WriterTInstances with WriterTFunctions {
}

private[data] sealed abstract class WriterTInstances extends WriterTInstances0 {
implicit def catsDataCommutativeMonadForWriterT[F[_], L](implicit F: CommutativeMonad[F], L: CommutativeMonoid[L]): CommutativeMonad[WriterT[F, L, ?]] =
new WriterTMonad[F, L] with CommutativeMonad[WriterT[F, L, ?]] {
implicit val F0: Monad[F] = F
implicit val L0: Monoid[L] = L
}
}

private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 {

implicit def catsDataMonadForWriterTId[L:Monoid]: Monad[WriterT[Id, L, ?]] =
catsDataMonadWriterForWriterT[Id, L]
Expand Down Expand Up @@ -93,7 +102,7 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 {
catsDataMonoidForWriterT[Id, L, V]
}

private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 {
private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 {
implicit def catsDataMonadCombineForWriterT[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] =
new WriterTMonadCombine[F, L] {
implicit val F0: MonadCombine[F] = F
Expand All @@ -110,7 +119,7 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1
catsDataSemigroupForWriterT[Id, L, V]
}

private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 {
private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
implicit def catsDataMonadFilterForWriterT[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] =
new WriterTMonadFilter[F, L] {
implicit val F0: MonadFilter[F] = F
Expand All @@ -126,7 +135,7 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2
catsDataCoflatMapForWriterT[Id, L]
}

private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
implicit def catsDataMonadWriterForWriterT[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadWriter[WriterT[F, L, ?], L] =
new WriterTMonadWriter[F, L] {
implicit val F0: Monad[F] = F
Expand All @@ -139,7 +148,7 @@ private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3
}
}

private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 {
implicit def catsDataAlternativeForWriterT[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] =
new WriterTAlternative[F, L] {
implicit val F0: Alternative[F] = F
Expand All @@ -148,7 +157,7 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4

}

private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 {
private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 {
implicit def catsDataApplicativeForWriterT[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] =
new WriterTApplicative[F, L] {
implicit val F0: Applicative[F] = F
Expand All @@ -161,7 +170,7 @@ private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5
}
}

private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 {
private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 {
implicit def catsDataFlatMapForWriterT1[F[_], L](implicit F: FlatMap[F], L: Monoid[L]): FlatMap[WriterT[F, L, ?]] =
new WriterTFlatMap1[F, L] {
implicit val F0: FlatMap[F] = F
Expand All @@ -174,15 +183,15 @@ private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6
}
}

private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 {
private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8 {
implicit def catsDataFlatMapForWriterT2[F[_], L](implicit F: Monad[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] =
new WriterTFlatMap2[F, L] {
implicit val F0: Monad[F] = F
implicit val L0: Semigroup[L] = L
}
}

private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8 {
private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 {

implicit def catsDataApplyForWriterT[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] =
new WriterTApply[F, L] {
Expand All @@ -191,7 +200,7 @@ private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8
}
}

private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 {
private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 {
implicit def catsDataCoflatMapForWriterT[F[_], L](implicit F: Functor[F]): CoflatMap[WriterT[F, L, ?]] =
new WriterTCoflatMap[F, L] {
implicit val F0: Functor[F] = F
Expand All @@ -202,15 +211,15 @@ private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9
}
}

private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 {
private[data] sealed abstract class WriterTInstances10 extends WriterTInstances11 {
implicit def catsDataMonadErrorForWriterT[F[_], L, E](implicit F: MonadError[F, E], L: Monoid[L]): MonadError[WriterT[F, L, ?], E] =
new WriterTMonadError[F, L, E] {
implicit val F0: MonadError[F, E] = F
implicit val L0: Monoid[L] = L
}
}

private[data] sealed abstract class WriterTInstances10 {
private[data] sealed abstract class WriterTInstances11 {
implicit def catsDataApplicativeErrorForWriterT[F[_], L, E](implicit F: ApplicativeError[F, E], L: Monoid[L]): ApplicativeError[WriterT[F, L, ?], E] =
new WriterTApplicativeError[F, L, E] {
implicit val F0: ApplicativeError[F, E] = F
Expand Down
3 changes: 3 additions & 0 deletions tests/src/test/scala/cats/tests/KleisliTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class KleisliTests extends CatsSuite {
checkAll("Kleisli[Option, Int, Int]", CartesianTests[Kleisli[Option, Int, ?]].cartesian[Int, Int, Int])
checkAll("Cartesian[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Cartesian[Kleisli[Option, Int, ?]]))

checkAll("Kleisli[Option, Int, ?]", CommutativeMonadTests[Kleisli[Option, Int, ?]].commutativeMonad[Int, Int, Int])
checkAll("CommutativeMonad[Kleisli[Option, Int, ?]]",SerializableTests.serializable(CommutativeMonad[Kleisli[Option, Int, ?]]))

{
implicit val catsDataArrowForKleisli = Kleisli.catsDataArrowForKleisli[List]
checkAll("Kleisli[List, Int, Int]", ArrowTests[Kleisli[List, ?, ?]].arrow[Int, Int, Int, Int, Int, Int])
Expand Down
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/NonEmptyListTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests

import cats.kernel.laws.{GroupLaws, OrderLaws}

import cats.data.NonEmptyList
import cats.data.{NonEmptyList, NonEmptyVector}
import cats.laws.discipline.{CommutativeComonadTests, SemigroupKTests, MonadTests, SerializableTests, NonEmptyTraverseTests, ReducibleTests, ComonadTests}
import cats.laws.discipline.arbitrary._

Expand Down
3 changes: 3 additions & 0 deletions tests/src/test/scala/cats/tests/WriterTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -391,4 +391,7 @@ class WriterTTests extends CatsSuite {
checkAll("WriterT[Option, ListWrapper[Int], ?]", MonadErrorTests[WriterT[Option, ListWrapper[Int], ?], Unit].monadError[Int, Int, Int])
checkAll("MonadError[WriterT[Option, ListWrapper[Int], ?], Unit]", SerializableTests.serializable(MonadError[WriterT[Option, ListWrapper[Int], ?], Unit]))
}

checkAll("WriterT[Option, Int, ?]", CommutativeMonadTests[WriterT[Option, Int, ?]].commutativeMonad[Int, Int, Int])
checkAll("CommutativeMonad[WriterT[Option, Int, ?]]",SerializableTests.serializable(CommutativeMonad[WriterT[Option, Int, ?]]))
}

0 comments on commit c5ab4a5

Please sign in to comment.