-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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 scala.util.control.TailCalls.TailRec instances #3041
Changes from 2 commits
40c7848
eb1271f
3f0177c
bc144d9
71ac6a4
cc304ca
24f308e
e24a602
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,4 +61,7 @@ trait AllInstancesBinCompat4 extends SortedMapInstancesBinCompat1 with MapInstan | |
|
||
trait AllInstancesBinCompat5 extends SortedSetInstancesBinCompat0 | ||
|
||
trait AllInstancesBinCompat6 extends SortedSetInstancesBinCompat1 with SortedMapInstancesBinCompat2 | ||
trait AllInstancesBinCompat6 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this break bincompat on 2.11? Only with the recent release candidates, I guess, so maybe it's fine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would assume so. I think we should only bump mima on actual releases (not including any pre-release). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @johnynek Right, but it's still useful to know, so we can decide whether we need to publish new pre-releases of cats-effect or Circe after a Cats pre-release, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the plan is to drop 2.11 on master immediately after 2.0.0 release (this evening). So we can add this to the root trait. |
||
extends SortedSetInstancesBinCompat1 | ||
with SortedMapInstancesBinCompat2 | ||
with TailRecInstances |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -378,6 +378,7 @@ sealed abstract private[cats] class EvalInstances extends EvalInstances0 { | |
def flatMap[A, B](fa: Eval[A])(f: A => Eval[B]): Eval[B] = fa.flatMap(f) | ||
def extract[A](la: Eval[A]): A = la.value | ||
def coflatMap[A, B](fa: Eval[A])(f: Eval[A] => B): Eval[B] = Later(f(fa)) | ||
override def unit: Eval[Unit] = Eval.Unit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unrelated? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. I added a comment, I just noticed it was missing while looking at Eval. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unrelated, but I noticed we could add this and avoid allocations for some folks that use |
||
} | ||
|
||
implicit val catsDeferForEval: Defer[Eval] = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package cats | ||
package instances | ||
|
||
import scala.util.control.TailCalls.{done, tailcall, TailRec} | ||
|
||
trait TailRecInstances { | ||
implicit val catsInstancesForTailRec: StackSafeMonad[TailRec] with Defer[TailRec] = | ||
new StackSafeMonad[TailRec] with Defer[TailRec] { | ||
def defer[A](fa: => TailRec[A]): TailRec[A] = tailcall(fa) | ||
|
||
def pure[A](a: A): TailRec[A] = done(a) | ||
|
||
override def map[A, B](fa: TailRec[A])(f: A => B): TailRec[B] = | ||
fa.map(f) | ||
|
||
def flatMap[A, B](fa: TailRec[A])(f: A => TailRec[B]): TailRec[B] = | ||
fa.flatMap(f) | ||
|
||
override val unit: TailRec[Unit] = done(()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package cats | ||
package tests | ||
|
||
import scala.util.control.TailCalls.{done, tailcall, TailRec} | ||
import org.scalacheck.{Arbitrary, Cogen, Gen} | ||
|
||
import Arbitrary.arbitrary | ||
|
||
import cats.laws.discipline.{DeferTests, MonadTests, SerializableTests} | ||
|
||
class TailRecSuite extends CatsSuite { | ||
|
||
implicit def tailRecArb[A: Arbitrary: Cogen]: Arbitrary[TailRec[A]] = | ||
Arbitrary( | ||
Gen.frequency( | ||
(3, arbitrary[A].map(done(_))), | ||
(1, Gen.lzy(arbitrary[(A, A => TailRec[A])].map { case (a, fn) => tailcall(fn(a)) })), | ||
(1, Gen.lzy(arbitrary[(TailRec[A], A => TailRec[A])].map { case (a, fn) => a.flatMap(fn) })) | ||
) | ||
) | ||
|
||
implicit def eqTailRec[A: Eq]: Eq[TailRec[A]] = | ||
Eq.by[TailRec[A], A](_.result) | ||
|
||
checkAll("TailRec[Int]", MonadTests[TailRec].monad[Int, Int, Int]) | ||
checkAll("Monad[TailRec]", SerializableTests.serializable(Monad[TailRec])) | ||
|
||
checkAll("TailRec[Int]", DeferTests[TailRec].defer[Int]) | ||
checkAll("Defer[TailRec]", SerializableTests.serializable(Defer[TailRec])) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Doing a search for "2.10" shows four or five other things like this we should do, but none of them look urgent.