Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Future instances to implicit scope #3572

Merged
merged 2 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion core/src/main/scala/cats/Invariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import cats.arrow.Arrow
import cats.kernel._
import simulacrum.typeclass
import cats.kernel.compat.scalaVersionSpecific._
import scala.annotation.implicitNotFound
import scala.collection.immutable.{Queue, SortedMap}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import scala.util.control.TailCalls.TailRec
import scala.annotation.implicitNotFound

/**
* Must obey the laws defined in cats.laws.InvariantLaws.
Expand Down Expand Up @@ -129,6 +130,10 @@ object Invariant extends ScalaVersionSpecificInvariantInstances with InvariantIn

implicit def catsInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] =
cats.instances.try_.catsStdInstancesForTry
implicit def catsInstancesForFuture(implicit
ec: ExecutionContext
): MonadError[Future, Throwable] with CoflatMap[Future] =
cats.instances.future.catsStdInstancesForFuture(ec)

implicit def catsContravariantMonoidalForOrder: ContravariantMonoidal[Order] =
cats.instances.order.catsContravariantMonoidalForOrder
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/Semigroupal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cats

import cats.kernel.CommutativeSemigroup
import scala.collection.immutable.{Queue, SortedMap, SortedSet}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import simulacrum.typeclass
import scala.annotation.implicitNotFound
Expand Down Expand Up @@ -50,6 +51,8 @@ import scala.annotation.implicitNotFound
object Semigroupal extends ScalaVersionSpecificSemigroupalInstances with SemigroupalArityFunctions {
implicit def catsSemigroupalForOption: Semigroupal[Option] = cats.instances.option.catsStdInstancesForOption
implicit def catsSemigroupalForTry: Semigroupal[Try] = cats.instances.try_.catsStdInstancesForTry
implicit def catsSemigroupalForFuture(implicit ec: ExecutionContext): Semigroupal[Future] =
cats.instances.future.catsStdInstancesForFuture(ec)
implicit def catsSemigroupalForList: Semigroupal[List] = cats.instances.list.catsStdInstancesForList
implicit def catsSemigroupalForVector: Semigroupal[Vector] = cats.instances.vector.catsStdInstancesForVector
implicit def catsSemigroupalForQueue: Semigroupal[Queue] = cats.instances.queue.catsStdInstancesForQueue
Expand Down
3 changes: 1 addition & 2 deletions js/src/test/scala/cats/tests/FutureTests.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cats.js.tests

import cats.Comonad
import cats.instances.FutureInstances
import cats.js.instances.Await
import cats.js.instances.future.futureComonad
import cats.kernel.Eq
Expand All @@ -15,7 +14,7 @@ import org.scalacheck.Arbitrary.arbitrary
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.concurrent.duration._

class FutureTests extends CatsSuite with FutureInstances {
class FutureTests extends CatsSuite {
// Replaces Scala.js's `JSExecutionContext.runNow`, which is removed in 1.0.
// TODO: We shouldn't do this! See: https://github.com/scala-js/scala-js/issues/2102
implicit private object RunNowExecutionContext extends ExecutionContextExecutor {
Expand Down
1 change: 0 additions & 1 deletion jvm/src/test/scala/cats/tests/FutureSuite.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cats.jvm.tests

import cats.instances.future._
import cats.kernel.{Eq, Semigroup}
import cats.kernel.laws.discipline.{MonoidTests => MonoidLawTests, SemigroupTests => SemigroupLawTests}
import cats.laws.discipline._
Expand Down
15 changes: 15 additions & 0 deletions kernel/src/main/scala/cats/kernel/Semigroup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cats.kernel

import scala.annotation.tailrec
import scala.collection.immutable.{BitSet, Queue, SortedMap, SortedSet}
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration.{Duration, FiniteDuration}
import scala.{specialized => sp}
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -250,6 +251,8 @@ private[kernel] trait MonoidInstances extends BandInstances {
cats.kernel.instances.either.catsDataMonoidForEither[A, B]
implicit def catsKernelMonoidForTry[A: Monoid]: Monoid[Try[A]] =
new TryMonoid[A](Monoid[A])
implicit def catsKernelMonoidForFuture[A](implicit A: Monoid[A], ec: ExecutionContext): Monoid[Future[A]] =
new FutureMonoid[A](A, ec)
implicit def catsKernelMonoidForOption[A: Semigroup]: Monoid[Option[A]] =
cats.kernel.instances.option.catsKernelStdMonoidForOption[A]
}
Expand Down Expand Up @@ -277,6 +280,8 @@ private[kernel] trait SemigroupInstances {
cats.kernel.instances.either.catsDataSemigroupForEither[A, B]
implicit def catsKernelSemigroupForTry[A: Semigroup]: Semigroup[Try[A]] =
new TrySemigroup[A](Semigroup[A])
implicit def catsKernelSemigroupForFuture[A](implicit A: Semigroup[A], ec: ExecutionContext): Semigroup[Future[A]] =
new FutureSemigroup[A](A, ec)
}

private class TryMonoid[A](A: Monoid[A]) extends TrySemigroup[A](A) with Monoid[Try[A]] {
Expand All @@ -291,3 +296,13 @@ private class TrySemigroup[A](A: Semigroup[A]) extends Semigroup[Try[A]] {
case (_, f) => f
}
}

private class FutureMonoid[A](A: Monoid[A], ec: ExecutionContext)
extends FutureSemigroup[A](A, ec)
with Monoid[Future[A]] {
def empty: Future[A] = Future.successful(A.empty)
}

private class FutureSemigroup[A](A: Semigroup[A], ec: ExecutionContext) extends Semigroup[Future[A]] {
def combine(x: Future[A], y: Future[A]): Future[A] = x.flatMap(xv => y.map(A.combine(xv, _))(ec))(ec)
}