Skip to content

Commit

Permalink
Merge pull request #696 from ceedubs/writert-instances
Browse files Browse the repository at this point in the history
Add more WriterT instances
  • Loading branch information
adelbertc committed Nov 25, 2015
2 parents efe4af7 + 355db32 commit 4fbe9dd
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 10 deletions.
73 changes: 67 additions & 6 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 {
}

private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 {
implicit def writerTMonad[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] =
new WriterTMonad[F, L] {
implicit val F0: Monad[F] = F
implicit def writerTMonadCombine[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] =
new WriterTMonadCombine[F, L] {
implicit val F0: MonadCombine[F] = F
implicit val L0: Monoid[L] = L
}

Expand All @@ -82,29 +82,63 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1
}

private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 {
implicit def writerTMonadFilter[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] =
new WriterTMonadFilter[F, L] {
implicit val F0: MonadFilter[F] = F
implicit val L0: Monoid[L] = L
}
}
private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
implicit def writerTMonad[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] =
new WriterTMonad[F, L] {
implicit val F0: Monad[F] = F
implicit val L0: Monoid[L] = L
}
}

private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
implicit def writerTAlternative[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] =
new WriterTAlternative[F, L] {
implicit val F0: Alternative[F] = F
implicit val L0: Monoid[L] = L
}
}

private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 {
implicit def writerTApplicative[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] =
new WriterTApplicative[F, L] {
implicit val F0: Applicative[F] = F
implicit val L0: Monoid[L] = L
}

implicit def writerTMonoidK[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] =
new WriterTMonoidK[F, L] {
implicit val F0: MonoidK[F] = F
}
}
private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {

private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 {
implicit def writerTFlatMap[F[_], L](implicit F: FlatMap[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] =
new WriterTFlatMap[F, L] {
implicit val F0: FlatMap[F] = F
implicit val L0: Semigroup[L] = L
}

implicit def writerTSemigroupK[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] =
new WriterTSemigroupK[F, L] {
implicit val F0: SemigroupK[F] = F
}
}

private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 {
implicit def writerTApply[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] =
new WriterTApply[F, L] {
implicit val F0: Apply[F] = F
implicit val L0: Semigroup[L] = L
}
}

private[data] sealed abstract class WriterTInstances4 {
private[data] sealed abstract class WriterTInstances7 {
implicit def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = new WriterTFunctor[F, L] {
implicit val F0: Functor[F] = F
}
Expand Down Expand Up @@ -149,6 +183,33 @@ private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L
fa.flatMap(f)
}

private[data] sealed trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] {
implicit def F0: SemigroupK[F]

def combine[A](x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] =
WriterT(F0.combine(x.run, y.run))
}

private[data] sealed trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, ?]] with WriterTSemigroupK[F, L] {
override implicit def F0: MonoidK[F]

def empty[A]: WriterT[F, L, A] = WriterT(F0.empty)
}

private[data] sealed trait WriterTAlternative[F[_], L] extends Alternative[WriterT[F, L, ?]] with WriterTMonoidK[F, L] with WriterTApplicative[F, L] {
override implicit def F0: Alternative[F]
}

private[data] sealed trait WriterTMonadFilter[F[_], L] extends MonadFilter[WriterT[F, L, ?]] with WriterTMonad[F, L] {
override implicit def F0: MonadFilter[F]

def empty[A]: WriterT[F, L, A] = WriterT(F0.empty)
}

private[data] sealed trait WriterTMonadCombine[F[_], L] extends MonadCombine[WriterT[F, L, ?]] with WriterTMonad[F, L] with WriterTAlternative[F, L] {
override implicit def F0: MonadCombine[F]
}

trait WriterTFunctions {
def putT[F[_], L, V](vf: F[V])(l: L)(implicit functorF: Functor[F]): WriterT[F, L, V] =
WriterT(functorF.map(vf)(v => (l, v)))
Expand Down
6 changes: 6 additions & 0 deletions tests/src/test/scala/cats/tests/ListWrapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ object ListWrapper {
}
}

def monoidK: MonoidK[ListWrapper] = monadCombine

def monadFilter: MonadFilter[ListWrapper] = monadCombine

def alternative: Alternative[ListWrapper] = monadCombine

def monoid[A]: Monoid[ListWrapper[A]] = monadCombine.algebra[A]

implicit def listWrapperArbitrary[A: Arbitrary]: Arbitrary[ListWrapper[A]] =
Expand Down
70 changes: 66 additions & 4 deletions tests/src/test/scala/cats/tests/WriterTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ class WriterTTests extends CatsSuite {
}
}

{
// F has a SemigroupK
implicit val F: SemigroupK[ListWrapper] = ListWrapper.semigroupK

checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", SemigroupKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].semigroupK[Int])
checkAll("SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]))
}

{
// F has a MonoidK
implicit val F: MonoidK[ListWrapper] = ListWrapper.monoidK

SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]

checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonoidKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monoidK[Int])
checkAll("MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]]))
}

{
// F has a Functor and L has no Semigroup
implicit val F: Functor[ListWrapper] = ListWrapper.functor
Expand All @@ -69,7 +87,7 @@ class WriterTTests extends CatsSuite {
{
// F has an Apply and L has a Semigroup
implicit val F: Apply[ListWrapper] = ListWrapper.monadCombine
implicit val L: Semigroup[ListWrapper[Int]] = ListWrapper.semigroupK.algebra[Int]
implicit val L: Semigroup[ListWrapper[Int]] = ListWrapper.semigroup[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", ApplyTests[WriterT[ListWrapper, ListWrapper[Int], ?]].apply[Int, Int, Int])
Expand All @@ -88,7 +106,7 @@ class WriterTTests extends CatsSuite {
{
// F has a FlatMap and L has a Semigroup
implicit val F: FlatMap[ListWrapper] = ListWrapper.monadCombine
implicit val L: Semigroup[ListWrapper[Int]] = ListWrapper.semigroupK.algebra[Int]
implicit val L: Semigroup[ListWrapper[Int]] = ListWrapper.semigroup[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Expand All @@ -111,7 +129,7 @@ class WriterTTests extends CatsSuite {
{
// F has an Applicative and L has a Monoid
implicit val F: Applicative[ListWrapper] = ListWrapper.monadCombine
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monadCombine.algebra[Int]
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Expand All @@ -134,7 +152,7 @@ class WriterTTests extends CatsSuite {
{
// F has a Monad and L has a Monoid
implicit val F: Monad[ListWrapper] = ListWrapper.monadCombine
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monadCombine.algebra[Int]
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Expand All @@ -161,4 +179,48 @@ class WriterTTests extends CatsSuite {
FlatMap[Logged]
Monad[Logged]
}

{
// F has an Alternative and L has a Monoid
implicit val F: Alternative[ListWrapper] = ListWrapper.alternative
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]]
checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", AlternativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].alternative[Int, Int, Int])
checkAll("Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]))
}

{
// F has a MonadFilter and L has a Monoid
implicit val F: MonadFilter[ListWrapper] = ListWrapper.monadFilter
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]]
FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]]
Monad[WriterT[ListWrapper, ListWrapper[Int], ?]]
checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadFilterTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monadFilter[Int, Int, Int])
checkAll("MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]]))
}

{
// F has a MonadCombine and L has a Monoid
implicit val F: MonadCombine[ListWrapper] = ListWrapper.monadCombine
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]

Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]
Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]
Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]]
FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]]
Monad[WriterT[ListWrapper, ListWrapper[Int], ?]]
MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]]
Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]
SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]
MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]]
checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadCombineTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monadCombine[Int, Int, Int])
checkAll("MonadCombine[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonadCombine[WriterT[ListWrapper, ListWrapper[Int], ?]]))
}
}

0 comments on commit 4fbe9dd

Please sign in to comment.