Skip to content

Commit

Permalink
Router bugfix: find the correct lambda right arrow
Browse files Browse the repository at this point in the history
  • Loading branch information
Albert Meltzer committed Feb 18, 2020
1 parent 21b5a53 commit d7b7725
Show file tree
Hide file tree
Showing 26 changed files with 2,358 additions and 1,537 deletions.
86 changes: 61 additions & 25 deletions repos/cats/tests/src/test/scala/cats/tests/CokleisliTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,65 @@ import cats.laws.discipline.{SemigroupKTests, MonoidKTests}

class CokleisliTests extends SlowCatsSuite {

implicit def cokleisliEq[F[_], A, B](implicit A: Arbitrary[F[A]], FB: Eq[B]): Eq[Cokleisli[F, A, B]] =
implicit def cokleisliEq[F[_], A, B](
implicit A: Arbitrary[F[A]],
FB: Eq[B]): Eq[Cokleisli[F, A, B]] =
Eq.by[Cokleisli[F, A, B], F[A] => B](_.run)

def cokleisliEqE[F[_], A](implicit A: Arbitrary[F[A]], FA: Eq[A]): Eq[Cokleisli[F, A, A]] =
def cokleisliEqE[F[_], A](
implicit A: Arbitrary[F[A]],
FA: Eq[A]): Eq[Cokleisli[F, A, A]] =
Eq.by[Cokleisli[F, A, A], F[A] => A](_.run)

implicit val iso = CartesianTests.Isomorphisms.invariant[Cokleisli[Option, Int, ?]]

checkAll("Cokleisli[Option, Int, Int]", CartesianTests[Cokleisli[Option, Int, ?]].cartesian[Int, Int, Int])
checkAll("Cartesian[Cokleisli[Option, Int, ?]", SerializableTests.serializable(Cartesian[Cokleisli[Option, Int, ?]]))

checkAll("Cokleisli[Option, Int, Int]", ApplicativeTests[Cokleisli[Option, Int, ?]].applicative[Int, Int, Int])
checkAll("Applicative[Cokleisli[Option, Int, ?]", SerializableTests.serializable(Applicative[Cokleisli[Option, Int, ?]]))

checkAll("Cokleisli[Option, Int, Int]", ProfunctorTests[Cokleisli[Option, ?, ?]].profunctor[Int, Int, Int, Int, Int, Int])
checkAll("Profunctor[Cokleisli[Option, ?, ?]", SerializableTests.serializable(Profunctor[Cokleisli[Option, ?, ?]]))

checkAll("Cokleisli[Option, Int, Int]", SplitTests[Cokleisli[Option, ?, ?]].split[Int, Int, Int, Int, Int, Int])
checkAll("Split[Cokleisli[Option, ?, ?]", SerializableTests.serializable(Split[Cokleisli[Option, ?, ?]]))
implicit val iso =
CartesianTests.Isomorphisms.invariant[Cokleisli[Option, Int, ?]]

checkAll(
"Cokleisli[Option, Int, Int]",
CartesianTests[Cokleisli[Option, Int, ?]].cartesian[Int, Int, Int])
checkAll(
"Cartesian[Cokleisli[Option, Int, ?]",
SerializableTests.serializable(Cartesian[Cokleisli[Option, Int, ?]]))

checkAll(
"Cokleisli[Option, Int, Int]",
ApplicativeTests[Cokleisli[Option, Int, ?]].applicative[Int, Int, Int])
checkAll(
"Applicative[Cokleisli[Option, Int, ?]",
SerializableTests.serializable(Applicative[Cokleisli[Option, Int, ?]]))

checkAll(
"Cokleisli[Option, Int, Int]",
ProfunctorTests[Cokleisli[Option, ?, ?]]
.profunctor[Int, Int, Int, Int, Int, Int])
checkAll(
"Profunctor[Cokleisli[Option, ?, ?]",
SerializableTests.serializable(Profunctor[Cokleisli[Option, ?, ?]]))

checkAll(
"Cokleisli[Option, Int, Int]",
SplitTests[Cokleisli[Option, ?, ?]].split[Int, Int, Int, Int, Int, Int])
checkAll(
"Split[Cokleisli[Option, ?, ?]",
SerializableTests.serializable(Split[Cokleisli[Option, ?, ?]]))

{
// Ceremony to help scalac to do the right thing, see also #267.
type CokleisliNEL[A, B] = Cokleisli[NonEmptyList, A, B]

implicit def ev0[A: Arbitrary, B: Arbitrary]: Arbitrary[CokleisliNEL[A, B]] =
implicit def ev0[A: Arbitrary, B: Arbitrary]
: Arbitrary[CokleisliNEL[A, B]] =
cokleisliArbitrary

implicit def ev1[A: Arbitrary, B: Eq]: Eq[CokleisliNEL[A, B]] =
cokleisliEq[NonEmptyList, A, B](oneAndArbitrary, Eq[B])

checkAll("Cokleisli[NonEmptyList, Int, Int]", ArrowTests[CokleisliNEL].arrow[Int, Int, Int, Int, Int, Int])
checkAll("Arrow[Cokleisli[NonEmptyList, ?, ?]]", SerializableTests.serializable(Arrow[CokleisliNEL]))
checkAll(
"Cokleisli[NonEmptyList, Int, Int]",
ArrowTests[CokleisliNEL].arrow[Int, Int, Int, Int, Int, Int])
checkAll(
"Arrow[Cokleisli[NonEmptyList, ?, ?]]",
SerializableTests.serializable(Arrow[CokleisliNEL]))
}

{
Expand All @@ -58,21 +85,30 @@ class CokleisliTests extends SlowCatsSuite {

{
implicit val cokleisliMonoidK = Cokleisli.cokleisliMonoidK[NonEmptyList]
checkAll("Cokleisli[NonEmptyList, Int, Int]", MonoidKTests[CokleisliNELE].monoidK[Int])
checkAll("MonoidK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]", SerializableTests.serializable(cokleisliMonoidK))
checkAll(
"Cokleisli[NonEmptyList, Int, Int]",
MonoidKTests[CokleisliNELE].monoidK[Int])
checkAll(
"MonoidK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]",
SerializableTests.serializable(cokleisliMonoidK))
}

{
implicit val cokleisliSemigroupK = Cokleisli.cokleisliSemigroupK[NonEmptyList]
checkAll("Cokleisli[NonEmptyList, Int, Int]", SemigroupKTests[CokleisliNELE].semigroupK[Int])
checkAll("SemigroupK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]", SerializableTests.serializable(cokleisliSemigroupK))
implicit val cokleisliSemigroupK =
Cokleisli.cokleisliSemigroupK[NonEmptyList]
checkAll(
"Cokleisli[NonEmptyList, Int, Int]",
SemigroupKTests[CokleisliNELE].semigroupK[Int])
checkAll(
"SemigroupK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]",
SerializableTests.serializable(cokleisliSemigroupK))
}

}

test("contramapValue with Id consistent with lmap"){
test("contramapValue with Id consistent with lmap") {
forAll { (c: Cokleisli[Id, Int, Long], f: Char => Int) =>
c.contramapValue[Char](f) should === (c.lmap(f))
c.contramapValue[Char](f) should ===(c.lmap(f))
}
}
}
65 changes: 35 additions & 30 deletions repos/cats/tests/src/test/scala/cats/tests/EvalTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,42 @@ import algebra.laws.{GroupLaws, OrderLaws}
class EvalTests extends CatsSuite {

/**
* Class for spooky side-effects and action-at-a-distance.
*
* It is basically a mutable counter that can be used to measure how
* many times an otherwise pure function is being evaluted.
*/
* Class for spooky side-effects and action-at-a-distance.
*
* It is basically a mutable counter that can be used to measure how
* many times an otherwise pure function is being evaluted.
*/
class Spooky(var counter: Int = 0) {
def increment(): Unit = counter += 1
}

/**
* This method creates a Eval[A] instance (along with a
* corresponding Spooky instance) from an initial `value` using the
* given `init` function.
*
* It will then proceed to call `value` 0-or-more times, verifying
* that the result is equal to `value`, and also that the
* appropriate number of evaluations are occuring using the
* `numCalls` function.
*
* In other words, each invocation of run says:
*
* 1. What underlying `value` to use.
* 2. How to create Eval instances (memoized, eager, or by-name).
* 3. How many times we expect the value to be computed.
*/
def runValue[A: Eq](value: A)(init: A => (Spooky, Eval[A]))(numCalls: Int => Int): Unit = {
* This method creates a Eval[A] instance (along with a
* corresponding Spooky instance) from an initial `value` using the
* given `init` function.
*
* It will then proceed to call `value` 0-or-more times, verifying
* that the result is equal to `value`, and also that the
* appropriate number of evaluations are occuring using the
* `numCalls` function.
*
* In other words, each invocation of run says:
*
* 1. What underlying `value` to use.
* 2. How to create Eval instances (memoized, eager, or by-name).
* 3. How many times we expect the value to be computed.
*/
def runValue[A: Eq](value: A)(init: A => (Spooky, Eval[A]))(
numCalls: Int => Int): Unit = {
var spin = 0
def nTimes(n: Int, numEvals: Int): Unit = {
val (spooky, lz) = init(value)
(0 until n).foreach { _ =>
val result = lz.value
result should === (value)
result should ===(value)
spin ^= result.##
}
spooky.counter should === (numEvals)
spooky.counter should ===(numEvals)
}
(0 to 2).foreach(n => nTimes(n, numCalls(n)))
}
Expand Down Expand Up @@ -80,14 +81,14 @@ class EvalTests extends CatsSuite {
runValue(999)(always)(n => n)
}

test(".value should evaluate only once on the result of .memoize"){
test(".value should evaluate only once on the result of .memoize") {
forAll { i: Eval[Int] =>
val spooky = new Spooky
val i2 = i.map(_ => spooky.increment).memoize
i2.value
spooky.counter should === (1)
spooky.counter should ===(1)
i2.value
spooky.counter should === (1)
spooky.counter should ===(1)
}
}

Expand All @@ -106,7 +107,9 @@ class EvalTests extends CatsSuite {

{
implicit val A = ListWrapper.semigroup[Int]
checkAll("Eval[ListWrapper[Int]]", GroupLaws[Eval[ListWrapper[Int]]].semigroup)
checkAll(
"Eval[ListWrapper[Int]]",
GroupLaws[Eval[ListWrapper[Int]]].semigroup)
}

{
Expand All @@ -116,7 +119,9 @@ class EvalTests extends CatsSuite {

{
implicit val A = ListWrapper.partialOrder[Int]
checkAll("Eval[ListWrapper[Int]]", OrderLaws[Eval[ListWrapper[Int]]].partialOrder)
checkAll(
"Eval[ListWrapper[Int]]",
OrderLaws[Eval[ListWrapper[Int]]].partialOrder)
}

{
Expand All @@ -132,14 +137,14 @@ class EvalTests extends CatsSuite {
test("cokleisli left identity") {
forAll { (fa: Eval[Int], f: Eval[Int] => Long) =>
val isEq = ComonadLaws[Eval].cokleisliLeftIdentity(fa, f)
isEq.lhs should === (isEq.rhs)
isEq.lhs should ===(isEq.rhs)
}
}

test("cokleisli right identity") {
forAll { (fa: Eval[Int], f: Eval[Int] => Long) =>
val isEq = ComonadLaws[Eval].cokleisliRightIdentity(fa, f)
isEq.lhs should === (isEq.rhs)
isEq.lhs should ===(isEq.rhs)
}
}
}
Loading

0 comments on commit d7b7725

Please sign in to comment.