Skip to content

Commit

Permalink
move instances into separate trait (#1659)
Browse files Browse the repository at this point in the history
* move instances into separate trait

* adding separate objects for piecemeal imports

* Adding implicit resolution tests for piecemeal imports for hierarchy

* Removing explicit implicitly and using apply method
  • Loading branch information
yilinwei authored and peterneyens committed May 28, 2017
1 parent ed03ce3 commit b722f2b
Show file tree
Hide file tree
Showing 18 changed files with 212 additions and 107 deletions.
12 changes: 1 addition & 11 deletions core/src/main/scala/cats/Cartesian.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,4 @@ import simulacrum.typeclass
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}

object Cartesian extends CartesianArityFunctions with KernelCartesianInstances

/**
* Cartesian instances for types that are housed in Kernel and therefore
* can't have instances for Cats type classes in their companion objects.
*/
private[cats] sealed trait KernelCartesianInstances {
implicit val catsInvariantSemigroup: Cartesian[Semigroup] = InvariantMonoidal.catsInvariantMonoidalSemigroup
implicit val catsInvariantMonoid: Cartesian[Monoid] = InvariantMonoidal.catsInvariantMonoidalMonoid
implicit val catsCartesianEq: Cartesian[Eq] = ContravariantCartesian.catsContravariantCartesianEq
}
object Cartesian extends CartesianArityFunctions
10 changes: 0 additions & 10 deletions core/src/main/scala/cats/ContravariantCartesian.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,3 @@ import simulacrum.typeclass
def G = Functor[G]
}
}

object ContravariantCartesian extends KernelContravariantCartesianInstances

private[cats] sealed trait KernelContravariantCartesianInstances {
implicit val catsContravariantCartesianEq: ContravariantCartesian[Eq] = new ContravariantCartesian[Eq] {
def contramap[A, B](fa: Eq[A])(fn: B => A): Eq[B] = fa.on(fn)
def product[A, B](fa: Eq[A], fb: Eq[B]): Eq[(A, B)] =
Eq.instance { (left, right) => fa.eqv(left._1, right._1) && fb.eqv(left._2, right._2) }
}
}
46 changes: 0 additions & 46 deletions core/src/main/scala/cats/InvariantMonoidal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,3 @@ import simulacrum.typeclass
@typeclass trait InvariantMonoidal[F[_]] extends Invariant[F] with Cartesian[F] {
def pure[A](a: A): F[A]
}

object InvariantMonoidal extends KernelInvariantMonoidalInstances

/**
* InvariantMonoidal instances for types that are housed in cats.kernel and therefore
* can't have instances for this type class in their companion objects.
*/
private[cats] trait KernelInvariantMonoidalInstances {
implicit val catsInvariantMonoidalSemigroup: InvariantMonoidal[Semigroup] = new InvariantMonoidal[Semigroup] {
def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2)
}

def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] = new Semigroup[B] {
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
override def combineAllOption(bs: TraversableOnce[B]): Option[B] =
fa.combineAllOption(bs.map(g)).map(f)
}

def pure[A](a: A): Semigroup[A] = new Semigroup[A] {
def combine(x: A, y: A): A = a
override def combineAllOption(as: TraversableOnce[A]): Option[A] =
if (as.isEmpty) None else Some(a)
}
}

implicit val catsInvariantMonoidalMonoid: InvariantMonoidal[Monoid] = new InvariantMonoidal[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)
}

def imap[A, B](fa: Monoid[A])(f: A => B)(g: B => A): Monoid[B] = new Monoid[B] {
val empty = f(fa.empty)
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
override def combineAll(bs: TraversableOnce[B]): B =
f(fa.combineAll(bs.map(g)))
}

def pure[A](a: A): Monoid[A] = new Monoid[A] {
val empty = a
def combine(x: A, y: A): A = a
override def combineAll(as: TraversableOnce[A]): A = a
}
}
}
29 changes: 0 additions & 29 deletions core/src/main/scala/cats/functor/Contravariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,3 @@ import simulacrum.typeclass
val G = Functor[G]
}
}

object Contravariant extends KernelContravariantInstances

/**
* Convariant instances for types that are housed in cats.kernel and therefore
* can't have instances for this type class in their companion objects.
*/
private[functor] sealed trait KernelContravariantInstances {
implicit def catsFunctorContravariantForEq: Contravariant[Eq] =
ContravariantCartesian.catsContravariantCartesianEq

implicit val catsFunctorContravariantForPartialOrder: Contravariant[PartialOrder] =
new Contravariant[PartialOrder] {
/** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
*/
def contramap[A, B](fa: PartialOrder[A])(f: B => A): PartialOrder[B] = fa.on(f)
}

implicit val catsFunctorContravariantForOrder: Contravariant[Order] =
new Contravariant[Order] {
/** Derive an `Order` for `B` given an `Order[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
*/
def contramap[A, B](fa: Order[A])(f: B => A): Order[B] = fa.on(f)
}
}
11 changes: 0 additions & 11 deletions core/src/main/scala/cats/functor/Invariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,3 @@ import simulacrum.typeclass
val G = Contravariant[G]
}
}

object Invariant extends KernelInvariantInstances

/**
* Invariant instances for types that are housed in cats.kernel and therefore
* can't have instances for this type class in their companion objects.
*/
private[functor] sealed trait KernelInvariantInstances {
implicit val catsFunctorInvariantForSemigroup: Invariant[Semigroup] = InvariantMonoidal.catsInvariantMonoidalSemigroup
implicit val catsFunctorInvariantForMonoid: Invariant[Monoid] = InvariantMonoidal.catsInvariantMonoidalMonoid
}
5 changes: 5 additions & 0 deletions core/src/main/scala/cats/instances/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ trait AllInstances
extends FunctionInstances
with StringInstances
with EitherInstances
with EqInstances
with ListInstances
with OptionInstances
with OrderInstances
with MonoidInstances
with PartialOrderInstances
with SemigroupInstances
with SetInstances
with StreamInstances
with VectorInstances
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/scala/cats/instances/eq.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package cats
package instances

trait EqInstances {
implicit val catsContravariantCartesianEq: ContravariantCartesian[Eq] = new ContravariantCartesian[Eq] {
def contramap[A, B](fa: Eq[A])(fn: B => A): Eq[B] = fa.on(fn)
def product[A, B](fa: Eq[A], fb: Eq[B]): Eq[(A, B)] =
Eq.instance { (left, right) => fa.eqv(left._1, right._1) && fb.eqv(left._2, right._2) }
}
}
26 changes: 26 additions & 0 deletions core/src/main/scala/cats/instances/monoid.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cats
package instances

trait MonoidInstances {

implicit val catsInvariantMonoidalMonoid: InvariantMonoidal[Monoid] = new InvariantMonoidal[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)
}

def imap[A, B](fa: Monoid[A])(f: A => B)(g: B => A): Monoid[B] = new Monoid[B] {
val empty = f(fa.empty)
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
override def combineAll(bs: TraversableOnce[B]): B =
f(fa.combineAll(bs.map(g)))
}

def pure[A](a: A): Monoid[A] = new Monoid[A] {
val empty = a
def combine(x: A, y: A): A = a
override def combineAll(as: TraversableOnce[A]): A = a
}
}

}
16 changes: 16 additions & 0 deletions core/src/main/scala/cats/instances/order.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cats
package instances

import cats.functor.Contravariant

trait OrderInstances {

implicit val catsFunctorContravariantForOrder: Contravariant[Order] =
new Contravariant[Order] {
/** Derive an `Order` for `B` given an `Order[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
*/
def contramap[A, B](fa: Order[A])(f: B => A): Order[B] = fa.on(f)
}
}
5 changes: 5 additions & 0 deletions core/src/main/scala/cats/instances/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ package object instances {
object all extends AllInstances

object either extends EitherInstances
object eq extends EqInstances
object function extends FunctionInstances
object order extends OrderInstances
object partialOrder extends PartialOrderInstances
object monoid extends MonoidInstances
object semigroup extends SemigroupInstances

object list extends ListInstances
object option extends OptionInstances
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/scala/cats/instances/partialOrder.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cats
package instances

import cats.functor.Contravariant

trait PartialOrderInstances {
implicit val catsFunctorContravariantForPartialOrder: Contravariant[PartialOrder] =
new Contravariant[PartialOrder] {
/** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
*/
def contramap[A, B](fa: PartialOrder[A])(f: B => A): PartialOrder[B] = fa.on(f)
}
}
24 changes: 24 additions & 0 deletions core/src/main/scala/cats/instances/semigroup.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cats
package instances

trait SemigroupInstances {

implicit val catsInvariantMonoidalSemigroup: InvariantMonoidal[Semigroup] = new InvariantMonoidal[Semigroup] {
def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2)
}

def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] = new Semigroup[B] {
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
override def combineAllOption(bs: TraversableOnce[B]): Option[B] =
fa.combineAllOption(bs.map(g)).map(f)
}

def pure[A](a: A): Semigroup[A] = new Semigroup[A] {
def combine(x: A, y: A): A = a
override def combineAllOption(as: TraversableOnce[A]): Option[A] =
if (as.isEmpty) None else Some(a)
}
}

}
2 changes: 2 additions & 0 deletions laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cats
package laws
package discipline

import cats.instances.eq._

import cats.laws.discipline.CartesianTests.Isomorphisms
import org.scalacheck.{Arbitrary, Cogen, Prop}
import Prop._
Expand Down
24 changes: 24 additions & 0 deletions tests/src/test/scala/cats/tests/EqTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class EqTests extends FunSuite {
{
import cats.implicits._
Invariant[Eq]
Contravariant[Eq]
Cartesian[Eq]
ContravariantCartesian[Eq]
}

{
import cats.instances.eq._
Invariant[Eq]
Contravariant[Eq]
Cartesian[Eq]
ContravariantCartesian[Eq]
}
}
22 changes: 22 additions & 0 deletions tests/src/test/scala/cats/tests/MonoidTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class MonoidTests extends FunSuite {
{
import cats.implicits._
Invariant[Monoid]
Cartesian[Monoid]
InvariantMonoidal[Monoid]
}

{
import cats.instances.monoid._
Invariant[Monoid]
Cartesian[Monoid]
InvariantMonoidal[Monoid]
}
}
20 changes: 20 additions & 0 deletions tests/src/test/scala/cats/tests/OrderTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cats
package tests

import cats.functor._

import org.scalatest._

class OrderTests extends FunSuite {
{
import cats.implicits._
Invariant[Order]
Contravariant[Order]
}

{
import cats.instances.order._
Invariant[Order]
Contravariant[Order]
}
}
20 changes: 20 additions & 0 deletions tests/src/test/scala/cats/tests/PartialOrderTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class PartialOrderTests extends FunSuite {
{
import cats.implicits._
Invariant[PartialOrder]
Contravariant[PartialOrder]
}

{
import cats.instances.partialOrder._
Invariant[PartialOrder]
Contravariant[PartialOrder]
}
}
22 changes: 22 additions & 0 deletions tests/src/test/scala/cats/tests/SemigroupTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cats
package tests

import org.scalatest._

import cats.functor._

class SemigroupTests extends FunSuite {
{
import cats.implicits._
Invariant[Semigroup]
Cartesian[Semigroup]
InvariantMonoidal[Semigroup]
}

{
import cats.instances.semigroup._
Invariant[Semigroup]
Cartesian[Semigroup]
InvariantMonoidal[Semigroup]
}
}

0 comments on commit b722f2b

Please sign in to comment.