Skip to content

Commit

Permalink
Add InvariantSemigroupal and ability to turn Monoidals to Monoids (#2088
Browse files Browse the repository at this point in the history
)

* Add InvariantSemigroupal and ability to turn Monoidals to Monoids

* Add Tests

* Add composition with Apply

* Add Mima exception

* More tests + Nested

* Remodel hierarchy

* Move monoid and semigroup functions to the instance

* More Tests

* Use def unit: F[Unit] as base for Monoidal

* Fix docs and free

* Fix duplicated mima exclusions

* Coverage

* Remove semigroup and monoid from typeclass and rename conquer to trivial

* Remove unecceasry instances

* use uinit for laws

* improve test coverage

* Add more mima exceptions

* Mima
  • Loading branch information
LukaJCB authored and kailuowang committed Dec 18, 2017
1 parent 02b819c commit 8d4d0b7
Show file tree
Hide file tree
Showing 46 changed files with 389 additions and 148 deletions.
20 changes: 20 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,26 @@ def mimaSettings(moduleName: String) = Seq(
exclude[DirectMissingMethodProblem]("cats.data.RWSTAlternative.sequence"),
exclude[ReversedMissingMethodProblem]("cats.MonadError.rethrow"),
exclude[ReversedMissingMethodProblem]("cats.syntax.MonadErrorSyntax.catsSyntaxMonadErrorRethrow"),
exclude[InheritedNewAbstractMethodProblem]("cats.InvariantSemigroupal.composeApply"),
exclude[DirectMissingMethodProblem]("cats.Semigroupal.catsSemigroupalForMonoid"),
exclude[ReversedMissingMethodProblem]("cats.instances.InvariantMonoidalInstances.catsSemigroupalForMonoid"),
exclude[DirectMissingMethodProblem]("cats.implicits.catsContravariantSemigroupalForPartialOrder"),
exclude[DirectMissingMethodProblem]("cats.instances.PartialOrderingInstances.catsContravariantSemigroupalForPartialOrdering"),
exclude[ReversedMissingMethodProblem]("cats.instances.PartialOrderingInstances.catsContravariantMonoidalForPartialOrdering"),
exclude[DirectMissingMethodProblem]("cats.instances.package#partialOrdering.catsContravariantSemigroupalForPartialOrdering"),
exclude[DirectMissingMethodProblem]("cats.instances.package#all.catsContravariantSemigroupalForPartialOrder"),
exclude[DirectMissingMethodProblem]("cats.instances.package#all.catsContravariantSemigroupalForPartialOrdering"),
exclude[DirectMissingMethodProblem]("cats.data.ConstInstances1.catsConstInvariantMonoidal"),
exclude[ReversedMissingMethodProblem]("cats.instances.PartialOrderInstances.cats$instances$PartialOrderInstances$_setter_$catsContravariantMonoidalForPartialOrder_="),
exclude[ReversedMissingMethodProblem]("cats.instances.PartialOrderingInstances.cats$instances$PartialOrderingInstances$_setter_$catsContravariantMonoidalForPartialOrdering_="),
exclude[DirectMissingMethodProblem]("cats.instances.package#partialOrder.catsContravariantSemigroupalForPartialOrder"),
exclude[DirectMissingMethodProblem]("cats.instances.PartialOrderInstances.catsContravariantSemigroupalForPartialOrder"),
exclude[ReversedMissingMethodProblem]("cats.instances.PartialOrderInstances.catsContravariantMonoidalForPartialOrder"),
exclude[DirectMissingMethodProblem]("cats.implicits.catsContravariantSemigroupalForPartialOrdering"),
exclude[InheritedNewAbstractMethodProblem]("cats.InvariantMonoidal.point"),
exclude[DirectMissingMethodProblem]("cats.InvariantMonoidal.pure"),
exclude[ReversedMissingMethodProblem]("cats.InvariantMonoidal.point"),
exclude[ReversedMissingMethodProblem]("cats.InvariantMonoidal.unit"),
exclude[DirectMissingMethodProblem]("cats.data.CokleisliArrow.id"),
exclude[IncompatibleResultTypeProblem]("cats.data.CokleisliArrow.id"),
exclude[DirectMissingMethodProblem]("cats.Apply#Ops.followedBy"),
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala/cats/Applicative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import simulacrum.typeclass
*
* Must obey the laws defined in cats.laws.ApplicativeLaws.
*/
@typeclass trait Applicative[F[_]] extends Apply[F] { self =>
@typeclass trait Applicative[F[_]] extends Apply[F] with InvariantMonoidal[F] { self =>



/**
* `pure` lifts any value into the Applicative Functor.
Expand Down Expand Up @@ -184,6 +186,7 @@ import simulacrum.typeclass
*/
def whenA[A](cond: Boolean)(f: => F[A]): F[Unit] =
if (cond) void(f) else pure(())

}

object Applicative {
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/cats/Apply.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import simulacrum.noop
* Must obey the laws defined in cats.laws.ApplyLaws.
*/
@typeclass(excludeParents = List("ApplyArityFunctions"))
trait Apply[F[_]] extends Functor[F] with Semigroupal[F] with ApplyArityFunctions[F] { self =>
trait Apply[F[_]] extends Functor[F] with InvariantSemigroupal[F] with ApplyArityFunctions[F] { self =>

/**
* Given a value and a function in the Apply context, applies the
Expand Down Expand Up @@ -94,6 +94,7 @@ trait Apply[F[_]] extends Functor[F] with Semigroupal[F] with ApplyArityFunction
val F = self
val G = Apply[G]
}

}

object Apply {
Expand Down
14 changes: 13 additions & 1 deletion core/src/main/scala/cats/Composed.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private[cats] trait ComposedApplicativeContravariantMonoidal[F[_], G[_]] extends
def F: Applicative[F]
def G: ContravariantMonoidal[G]

override def unit[A]: F[G[A]] = F.pure(G.unit)
override def unit: F[G[Unit]] = F.pure(G.unit)

override def contramap[A, B](fa: F[G[A]])(f: B => A): F[G[B]] =
F.map(fa)(G.contramap(_)(f))
Expand All @@ -144,6 +144,18 @@ private[cats] trait ComposedSemigroupal[F[_], G[_]] extends ContravariantSemigro
}
}

private[cats] trait ComposedInvariantApplySemigroupal[F[_], G[_]] extends InvariantSemigroupal[λ[α => F[G[α]]]] with ComposedInvariantCovariant[F, G] { outer =>
def F: InvariantSemigroupal[F]
def G: Apply[G]

def product[A, B](fa: F[G[A]], fb: F[G[B]]): F[G[(A, B)]] =
F.imap(F.product(fa, fb)) { case (ga, gb) =>
G.map2(ga, gb)(_ -> _)
} { g: G[(A, B)] =>
(G.map(g)(_._1), G.map(g)(_._2))
}
}

private[cats] trait ComposedCovariantContravariant[F[_], G[_]] extends Contravariant[λ[α => F[G[α]]]] { outer =>
def F: Functor[F]
def G: Contravariant[G]
Expand Down
16 changes: 12 additions & 4 deletions core/src/main/scala/cats/ContravariantMonoidal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,20 @@ import simulacrum.typeclass
* Based on ekmett's contravariant library:
* https://hackage.haskell.org/package/contravariant-1.4/docs/Data-Functor-Contravariant-Divisible.html
*/
@typeclass trait ContravariantMonoidal[F[_]] extends ContravariantSemigroupal[F] { self =>
@typeclass trait ContravariantMonoidal[F[_]] extends ContravariantSemigroupal[F] with InvariantMonoidal[F] {
/**
* `unit` produces an instance of `F` for any type `A`
* `trivial` produces an instance of `F` for any type `A`
* that is trivial with respect to `contramap2` along
* the diagonal
*/
def unit[A]: F[A]
def trivial[A]: F[A] = contramap(unit)(_ => ())

}
object ContravariantMonoidal extends SemigroupalArityFunctions {
def monoid[F[_], A](implicit f: ContravariantMonoidal[F]): Monoid[F[A]] =
new ContravariantMonoidalMonoid[F, A](f)
}

private[cats] class ContravariantMonoidalMonoid[F[_], A](f: ContravariantMonoidal[F]) extends ContravariantSemigroupalSemigroup[F, A](f) with Monoid[F[A]] {
def empty: F[A] = f.trivial
}
object ContravariantMonoidal extends SemigroupalArityFunctions
14 changes: 12 additions & 2 deletions core/src/main/scala/cats/ContravariantSemigroupal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ import simulacrum.typeclass
* [[ContravariantSemigroupal]] is nothing more than something both contravariant
* and Semigroupal. It comes up enough to be useful, and composes well
*/
@typeclass trait ContravariantSemigroupal[F[_]] extends Semigroupal[F] with Contravariant[F] { self =>
@typeclass trait ContravariantSemigroupal[F[_]] extends InvariantSemigroupal[F] with Contravariant[F] { self =>
override def composeFunctor[G[_]: Functor]: ContravariantSemigroupal[λ[α => F[G[α]]]] =
new ComposedSemigroupal[F, G] {
def F = self
def G = Functor[G]
}

}

object ContravariantSemigroupal extends SemigroupalArityFunctions {
def semigroup[F[_], A](implicit f: ContravariantSemigroupal[F]): Semigroup[F[A]] =
new ContravariantSemigroupalSemigroup[F, A](f)
}

private[cats] class ContravariantSemigroupalSemigroup[F[_], A](f: ContravariantSemigroupal[F]) extends Semigroup[F[A]] {
def combine(a: F[A], b: F[A]): F[A] =
ContravariantSemigroupal.contramap2(a, b)((a: A) => (a, a))(f, f)
}
object ContravariantSemigroupal extends SemigroupalArityFunctions
32 changes: 30 additions & 2 deletions core/src/main/scala/cats/InvariantMonoidal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@ import simulacrum.typeclass
*
* Must obey the laws defined in cats.laws.InvariantMonoidalLaws.
*/
@typeclass trait InvariantMonoidal[F[_]] extends Invariant[F] with Semigroupal[F] {
def pure[A](a: A): F[A]
@typeclass trait InvariantMonoidal[F[_]] extends InvariantSemigroupal[F] {
/**
* `point` lifts any value into a Monoidal Functor.
*
* Example:
* {{{
* scala> import cats.implicits._
*
* scala> InvariantMonoidal[Option].point(10)
* res0: Option[Int] = Some(10)
* }}}
*/
def point[A](a: A): F[A] = imap(unit)(_ => a)(_ => ())

def unit: F[Unit]


}

object InvariantMonoidal {
/**
* Gives a `Monoid` instance if A itself has a `Monoid` instance.
*/
def monoid[F[_], A](implicit F: InvariantMonoidal[F], A: Monoid[A]): Monoid[F[A]] =
new InvariantMonoidalMonoid[F, A](F, A)
}


private[cats] class InvariantMonoidalMonoid[F[_], A](f: InvariantMonoidal[F], monoid: Monoid[A]) extends InvariantSemigroupalSemigroup(f, monoid) with Monoid[F[A]] {
def empty: F[A] = f.point(monoid.empty)
}
30 changes: 30 additions & 0 deletions core/src/main/scala/cats/InvariantSemigroupal.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cats

import simulacrum.typeclass

/**
* [[InvariantSemigroupal]] is nothing more than something both invariant
* and Semigroupal. It comes up enough to be useful, and composes well
*/
@typeclass trait InvariantSemigroupal[F[_]] extends Semigroupal[F] with Invariant[F] { self =>

def composeApply[G[_]: Apply]: InvariantSemigroupal[λ[α => F[G[α]]]] =
new ComposedInvariantApplySemigroupal[F, G] {
def F = self
def G = Apply[G]
}

}

object InvariantSemigroupal extends SemigroupalArityFunctions {
/**
* Gives a `Semigroup` instance if A itself has a `Semigroup` instance.
*/
def semigroup[F[_], A](implicit F: InvariantSemigroupal[F], A: Semigroup[A]): Semigroup[F[A]] =
new InvariantSemigroupalSemigroup[F, A](F, A)
}

private[cats] class InvariantSemigroupalSemigroup[F[_], A](f: InvariantSemigroupal[F], sg: Semigroup[A]) extends Semigroup[F[A]] {
def combine(a: F[A], b: F[A]): F[A] =
InvariantSemigroupal.imap2(a, b)(sg.combine)(a => (a, a))(f, f)
}
9 changes: 1 addition & 8 deletions core/src/main/scala/cats/Semigroupal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,4 @@ import simulacrum.typeclass
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}

object Semigroupal extends SemigroupalArityFunctions {
implicit def catsSemigroupalForMonoid: Semigroupal[Monoid] = new Semigroupal[Monoid] {
def product[A, B](fa: Monoid[A], fb: Monoid[B]): Monoid[(A, B)] = new Monoid[(A, B)] {
val empty = fa.empty -> fb.empty
def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2)
}
}
}
object Semigroupal extends SemigroupalArityFunctions
12 changes: 1 addition & 11 deletions core/src/main/scala/cats/data/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 {
}

implicit def catsDataContravariantMonoidalForConst[D: Monoid]: ContravariantMonoidal[Const[D, ?]] = new ContravariantMonoidal[Const[D, ?]] {
override def unit[A] = Const.empty[D, A]
override def unit = Const.empty[D, Unit]
override def contramap[A, B](fa: Const[D, A])(f: B => A): Const[D, B] =
fa.retag[B]
override def product[A, B](fa: Const[D, A], fb: Const[D, B]): Const[D, (A, B)] =
Expand Down Expand Up @@ -135,16 +135,6 @@ private[data] sealed abstract class ConstInstances0 extends ConstInstances1 {
}

private[data] sealed abstract class ConstInstances1 {
implicit def catsConstInvariantMonoidal[C: Monoid]: InvariantMonoidal[Const[C, ?]] = new InvariantMonoidal[Const[C, ?]] {
def pure[A](a: A): Const[C, A] =
Const.empty

def imap[A, B](fa: Const[C, A])(f: A => B)(g: B => A): Const[C, B] =
fa.retag[B]

def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] =
fa.retag[(A, B)] combine fb.retag[(A, B)]
}

implicit def catsDataEqForConst[A: Eq, B]: Eq[Const[A, B]] = new Eq[Const[A, B]] {
def eqv(x: Const[A, B], y: Const[A, B]): Boolean =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/IdT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private[data] sealed trait IdTApplicative[F[_]] extends Applicative[IdT[F, ?]] w
private[data] sealed trait IdTContravariantMonoidal[F[_]] extends ContravariantMonoidal[IdT[F, ?]] {
implicit val F0: ContravariantMonoidal[F]

override def unit[A]: IdT[F, A] = IdT(F0.unit[A])
override def unit: IdT[F, Unit] = IdT(F0.unit)

override def contramap[A, B](fa: IdT[F, A])(f: B => A): IdT[F, B] =
IdT(F0.contramap(fa.value)(f))
Expand Down
10 changes: 3 additions & 7 deletions core/src/main/scala/cats/data/IndexedStateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ private[data] sealed abstract class IndexedStateTInstances extends IndexedStateT
implicit def catsDataAlternativeForIndexedStateT[F[_], S](implicit FM: Monad[F],
FA: Alternative[F]): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] =
new IndexedStateTAlternative[F, S] { implicit def F = FM; implicit def G = FA }

implicit def catsDataContravariantMonoidalForIndexedStateT[F[_], S](implicit FD: ContravariantMonoidal[F],
FA: Applicative[F]): ContravariantMonoidal[IndexedStateT[F, S, S, ?]] =
new IndexedStateTContravariantMonoidal[F, S] { implicit def F = FD; implicit def G = FA }
}

private[data] sealed abstract class IndexedStateTInstances1 extends IndexedStateTInstances2 {
Expand Down Expand Up @@ -387,11 +383,11 @@ private[data] sealed abstract class IndexedStateTContravariantMonoidal[F[_], S]
implicit def F: ContravariantMonoidal[F]
implicit def G: Applicative[F]

override def unit[A]: IndexedStateT[F, S, S, A] =
IndexedStateT.applyF(G.pure((s: S) => F.unit[(S, A)]))
override def unit: IndexedStateT[F, S, S, Unit] =
IndexedStateT.applyF(G.pure((s: S) => F.trivial[(S, Unit)]))

override def contramap[A, B](fa: IndexedStateT[F, S, S, A])(f: B => A): IndexedStateT[F, S, S, B] =
contramap2(fa, unit)(((a: A) => (a, a)) compose f)
contramap2(fa, trivial)(((a: A) => (a, a)) compose f)

override def product[A, B](fa: IndexedStateT[F, S, S, A], fb: IndexedStateT[F, S, S, B]): IndexedStateT[F, S, S, (A, B)] =
contramap2(fa, fb)(identity)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ private[data] trait KleisliAlternative[F[_], A] extends Alternative[Kleisli[F, A
private[data] sealed trait KleisliContravariantMonoidal[F[_], D] extends ContravariantMonoidal[Kleisli[F, D, ?]] {
implicit def F: ContravariantMonoidal[F]

override def unit[A]: Kleisli[F, D, A] = Kleisli(Function.const(F.unit[A]))
override def unit: Kleisli[F, D, Unit] = Kleisli(Function.const(F.unit))

override def contramap[A, B](fa: Kleisli[F, D, A])(f: B => A): Kleisli[F, D, B] =
Kleisli(d => F.contramap(fa.run(d))(f))
Expand Down
25 changes: 21 additions & 4 deletions core/src/main/scala/cats/data/Nested.scala
Original file line number Diff line number Diff line change
Expand Up @@ -147,27 +147,34 @@ private[data] sealed abstract class NestedInstances8 extends NestedInstances9 {
}

private[data] sealed abstract class NestedInstances9 extends NestedInstances10 {
implicit def catsDataInvariantSemigroupalApplyForNested[F[_]: InvariantSemigroupal, G[_]: Apply]: InvariantSemigroupal[Nested[F, G, ?]] =
new NestedInvariantSemigroupalApply[F, G] {
val FG: InvariantSemigroupal[λ[α => F[G[α]]]] = InvariantSemigroupal[F].composeApply[G]
}
}

private[data] sealed abstract class NestedInstances10 extends NestedInstances11 {
implicit def catsDataFunctorForNested[F[_]: Functor, G[_]: Functor]: Functor[Nested[F, G, ?]] =
new NestedFunctor[F, G] {
val FG: Functor[λ[α => F[G[α]]]] = Functor[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances10 extends NestedInstances11 {
private[data] sealed abstract class NestedInstances11 extends NestedInstances12 {
implicit def catsDataInvariantForNested[F[_]: Invariant, G[_]: Invariant]: Invariant[Nested[F, G, ?]] =
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances11 extends NestedInstances12 {
private[data] sealed abstract class NestedInstances12 extends NestedInstances13 {
implicit def catsDataInvariantForCovariantNested[F[_]: Invariant, G[_]: Functor]: Invariant[Nested[F, G, ?]] =
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeFunctor[G]
}
}

private[data] sealed abstract class NestedInstances12 {
private[data] sealed abstract class NestedInstances13 {
implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant]: Invariant[Nested[F, G, ?]] =
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeContravariant[G]
Expand Down Expand Up @@ -284,11 +291,21 @@ private[data] trait NestedContravariant[F[_], G[_]] extends Contravariant[Nested
private[data] trait NestedContravariantMonoidal[F[_], G[_]] extends ContravariantMonoidal[Nested[F, G, ?]] {
def FG: ContravariantMonoidal[λ[α => F[G[α]]]]

def unit[A]: Nested[F, G, A] = Nested(FG.unit)
def unit: Nested[F, G, Unit] = Nested(FG.unit)

def contramap[A, B](fa: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
Nested(FG.contramap(fa.value)(f))

def product[A, B](fa: Nested[F, G, A], fb: Nested[F, G, B]): Nested[F, G, (A, B)] =
Nested(FG.product(fa.value, fb.value))
}

private[data] trait NestedInvariantSemigroupalApply[F[_], G[_]] extends InvariantSemigroupal[Nested[F, G, ?]] {
def FG: InvariantSemigroupal[λ[α => F[G[α]]]]

def imap[A, B](fa: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(FG.imap(fa.value)(f)(g))

def product[A, B](fa: Nested[F, G, A], fb: Nested[F, G, B]): Nested[F, G, (A, B)] =
Nested(FG.product(fa.value, fb.value))
}
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private trait OptionTMonadError[F[_], E] extends MonadError[OptionT[F, ?], E] wi
private trait OptionTContravariantMonoidal[F[_]] extends ContravariantMonoidal[OptionT[F, ?]] {
def F: ContravariantMonoidal[F]

override def unit[A]: OptionT[F, A] = OptionT (F.unit)
override def unit: OptionT[F, Unit] = OptionT(F.trivial)

override def contramap[A, B](fa: OptionT[F, A])(f: B => A): OptionT[F, B] =
OptionT(F.contramap(fa.value)(_ map f))
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Tuple2K.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private[data] sealed trait Tuple2KContravariant[F[_], G[_]] extends Contravarian
private[data] sealed trait Tuple2KContravariantMonoidal[F[_], G[_]] extends ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] {
def F: ContravariantMonoidal[F]
def G: ContravariantMonoidal[G]
def unit[A]: Tuple2K[F, G, A] = Tuple2K(F.unit, G.unit)
def unit: Tuple2K[F, G, Unit] = Tuple2K(F.unit, G.unit)
def product[A, B](fa: Tuple2K[F, G, A], fb: Tuple2K[F, G, B]): Tuple2K[F, G, (A, B)] =
Tuple2K(F.product(fa.first, fb.first), G.product(fa.second, fb.second))
def contramap[A, B](fa: Tuple2K[F, G, A])(f: B => A): Tuple2K[F, G, B] =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ private[data] sealed trait WriterTAlternative[F[_], L] extends Alternative[Write
private[data] sealed trait WriterTContravariantMonoidal[F[_], L] extends ContravariantMonoidal[WriterT[F, L, ?]] {
implicit def F0: ContravariantMonoidal[F]

override def unit[A]: WriterT[F, L, A] = WriterT(F0.unit[(L, A)])
override def unit: WriterT[F, L, Unit] = WriterT(F0.trivial[(L, Unit)])

override def contramap[A, B](fa: WriterT[F, L, A])(f: B => A): WriterT[F, L, B] =
WriterT(F0.contramap(fa.run)((d: (L, B)) => (d._1, f(d._2))))
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/instances/eq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait EqInstances extends kernel.instances.EqInstances {
* Defaults to the trivial equivalence relation
* contracting the type to a point
*/
def unit[A]: Eq[A] = Eq.allEqual
def unit: Eq[Unit] = Eq.allEqual

/** Derive an `Eq` for `B` given an `Eq[A]` and a function `B => A`.
*
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/equiv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ trait EquivInstances {
* Defaults to trivially contracting the type
* to a point
*/
def unit[A]: Equiv[A] = new Equiv[A] {
def equiv(x: A, y: A): Boolean = true
def unit: Equiv[Unit] = new Equiv[Unit] {
def equiv(x: Unit, y: Unit): Boolean = true
}

/** Derive an `Equiv` for `B` given an `Equiv[A]` and a function `B => A`.
Expand Down
Loading

0 comments on commit 8d4d0b7

Please sign in to comment.