-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make kernel laws consistent with core laws (#1922)
* Make GroupLaws consistent with cats-core * Make OrderLaws consistent with core * Port tests * Update lawtesting docs * Remove unused machinery * Remove duplication of IsEq * Cleanup * Add Serializable to LawTests * Rename to -LawTests * Fix BoundedSemilattice parents * Add id * Fix lawtesting docs * Restructure order law tests * Move IsEq * Convert HashLaws to new setup * Readd function0 hash test * Add mima exception * Rename to ascending order
- Loading branch information
1 parent
4ffd3a1
commit 9ae4dc4
Showing
65 changed files
with
1,011 additions
and
763 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
kernel-laws/src/main/scala/cats/kernel/laws/BandLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cats.kernel.laws | ||
|
||
import cats.kernel.Band | ||
|
||
trait BandLaws[A] extends SemigroupLaws[A] { | ||
override implicit def S: Band[A] | ||
|
||
def idempotence(x: A): IsEq[A] = | ||
S.combine(x, x) <-> x | ||
|
||
} | ||
|
||
object BandLaws { | ||
def apply[A](implicit ev: Band[A]): BandLaws[A] = | ||
new BandLaws[A] { def S: Band[A] = ev } | ||
} |
27 changes: 0 additions & 27 deletions
27
kernel-laws/src/main/scala/cats/kernel/laws/BaseLaws.scala
This file was deleted.
Oops, something went wrong.
13 changes: 13 additions & 0 deletions
13
kernel-laws/src/main/scala/cats/kernel/laws/BoundedSemilatticeLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package cats.kernel.laws | ||
|
||
import cats.kernel.BoundedSemilattice | ||
|
||
trait BoundedSemilatticeLaws[A] extends CommutativeMonoidLaws[A] with SemilatticeLaws[A] { | ||
override implicit def S: BoundedSemilattice[A] | ||
|
||
} | ||
|
||
object BoundedSemilatticeLaws { | ||
def apply[A](implicit ev: BoundedSemilattice[A]): BoundedSemilatticeLaws[A] = | ||
new BoundedSemilatticeLaws[A] { def S: BoundedSemilattice[A] = ev } | ||
} |
13 changes: 13 additions & 0 deletions
13
kernel-laws/src/main/scala/cats/kernel/laws/CommutativeGroupLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package cats | ||
package kernel | ||
package laws | ||
|
||
|
||
trait CommutativeGroupLaws[A] extends GroupLaws[A] with CommutativeMonoidLaws[A] { | ||
override implicit def S: CommutativeGroup[A] | ||
} | ||
|
||
object CommutativeGroupLaws { | ||
def apply[A](implicit ev: CommutativeGroup[A]): CommutativeGroupLaws[A] = | ||
new CommutativeGroupLaws[A] { def S: CommutativeGroup[A] = ev } | ||
} |
13 changes: 13 additions & 0 deletions
13
kernel-laws/src/main/scala/cats/kernel/laws/CommutativeMonoidLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package cats.kernel.laws | ||
|
||
import cats.kernel.CommutativeMonoid | ||
|
||
trait CommutativeMonoidLaws[A] extends MonoidLaws[A] with CommutativeSemigroupLaws[A] { | ||
override implicit def S: CommutativeMonoid[A] | ||
|
||
} | ||
|
||
object CommutativeMonoidLaws { | ||
def apply[A](implicit ev: CommutativeMonoid[A]): CommutativeMonoidLaws[A] = | ||
new CommutativeMonoidLaws[A] { def S: CommutativeMonoid[A] = ev } | ||
} |
16 changes: 16 additions & 0 deletions
16
kernel-laws/src/main/scala/cats/kernel/laws/CommutativeSemigroupLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cats.kernel.laws | ||
|
||
import cats.kernel.CommutativeSemigroup | ||
|
||
trait CommutativeSemigroupLaws[A] extends SemigroupLaws[A] { | ||
override implicit def S: CommutativeSemigroup[A] | ||
|
||
def commutative(x: A, y: A): IsEq[A] = | ||
S.combine(x, y) <-> S.combine(y, x) | ||
|
||
} | ||
|
||
object CommutativeSemigroupLaws { | ||
def apply[A](implicit ev: CommutativeSemigroup[A]): CommutativeSemigroupLaws[A] = | ||
new CommutativeSemigroupLaws[A] { def S: CommutativeSemigroup[A] = ev } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package cats.kernel.laws | ||
|
||
import cats.kernel.Eq | ||
|
||
trait EqLaws[A] { | ||
|
||
implicit def E: Eq[A] | ||
|
||
def reflexitivityEq(x: A): IsEq[A] = | ||
x <-> x | ||
|
||
def symmetryEq(x: A, y: A): IsEq[Boolean] = | ||
E.eqv(x, y) <-> E.eqv(y, x) | ||
|
||
def antiSymmetryEq(x: A, y: A, f: A => A): IsEq[Boolean] = | ||
(!E.eqv(x, y) || E.eqv(f(x), f(y))) <-> true | ||
|
||
def transitivityEq(x: A, y: A, z: A): IsEq[Boolean] = | ||
(!(E.eqv(x, y) && E.eqv(y, z)) || E.eqv(x, z)) <-> true | ||
|
||
} | ||
|
||
object EqLaws { | ||
def apply[A](implicit ev: Eq[A]): EqLaws[A] = | ||
new EqLaws[A] { def E: Eq[A] = ev } | ||
} |
104 changes: 13 additions & 91 deletions
104
kernel-laws/src/main/scala/cats/kernel/laws/GroupLaws.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,23 @@ | ||
package cats.kernel | ||
package laws | ||
|
||
import cats.kernel._ | ||
import cats.kernel.instances.option._ | ||
|
||
import org.typelevel.discipline.Laws | ||
trait GroupLaws[A] extends MonoidLaws[A] { | ||
override implicit def S: Group[A] | ||
|
||
import org.scalacheck.{Arbitrary, Prop} | ||
import org.scalacheck.Prop._ | ||
def leftInverse(x: A): IsEq[A] = | ||
S.empty <-> S.combine(S.inverse(x), x) | ||
|
||
object GroupLaws { | ||
def apply[A : Eq : Arbitrary]: GroupLaws[A] = new GroupLaws[A] { | ||
def Equ = Eq[A] | ||
def Arb = implicitly[Arbitrary[A]] | ||
} | ||
} | ||
|
||
trait GroupLaws[A] extends Laws { | ||
|
||
implicit def Equ: Eq[A] | ||
implicit def Arb: Arbitrary[A] | ||
|
||
// groups | ||
|
||
def semigroup(implicit A: Semigroup[A]): GroupProperties = new GroupProperties( | ||
name = "semigroup", | ||
parents = Nil, | ||
Rules.serializable(A), | ||
Rules.associativity(A.combine), | ||
Rules.repeat1("combineN")(A.combineN), | ||
Rules.repeat2("combineN", "|+|")(A.combineN)(A.combine), | ||
"combineAllOption" -> forAll { (xs: Vector[A]) => | ||
A.combineAllOption(xs) ?== xs.reduceOption(A.combine) | ||
} | ||
) | ||
|
||
def band(implicit A: Band[A]): GroupProperties = new GroupProperties( | ||
name = "band", | ||
parents = List(semigroup), | ||
Rules.idempotence(A.combine), | ||
"isIdempotent" -> Semigroup.isIdempotent[A] | ||
) | ||
|
||
def commutativeSemigroup(implicit A: CommutativeSemigroup[A]): GroupProperties = new GroupProperties( | ||
name = "commutative semigroup", | ||
parents = List(semigroup), | ||
Rules.commutative(A.combine) | ||
) | ||
def rightInverse(x: A): IsEq[A] = | ||
S.empty <-> S.combine(x, S.inverse(x)) | ||
|
||
def semilattice(implicit A: Semilattice[A]): GroupProperties = new GroupProperties( | ||
name = "semilattice", | ||
parents = List(band, commutativeSemigroup) | ||
) | ||
|
||
def monoid(implicit A: Monoid[A]): GroupProperties = new GroupProperties( | ||
name = "monoid", | ||
parents = List(semigroup), | ||
Rules.leftIdentity(A.empty)(A.combine), | ||
Rules.rightIdentity(A.empty)(A.combine), | ||
Rules.repeat0("combineN", "id", A.empty)(A.combineN), | ||
Rules.collect0("combineAll", "id", A.empty)(A.combineAll), | ||
Rules.isId("isEmpty", A.empty)(A.isEmpty), | ||
"combineAll" -> forAll { (xs: Vector[A]) => | ||
A.combineAll(xs) ?== (A.empty +: xs).reduce(A.combine) | ||
} | ||
) | ||
|
||
def commutativeMonoid(implicit A: CommutativeMonoid[A]): GroupProperties = new GroupProperties( | ||
name = "commutative monoid", | ||
parents = List(monoid, commutativeSemigroup) | ||
) | ||
|
||
def boundedSemilattice(implicit A: BoundedSemilattice[A]): GroupProperties = new GroupProperties( | ||
name = "boundedSemilattice", | ||
parents = List(commutativeMonoid, semilattice) | ||
) | ||
|
||
def group(implicit A: Group[A]): GroupProperties = new GroupProperties( | ||
name = "group", | ||
parents = List(monoid), | ||
Rules.leftInverse(A.empty)(A.combine)(A.inverse), | ||
Rules.rightInverse(A.empty)(A.combine)(A.inverse), | ||
Rules.consistentInverse("remove")(A.remove)(A.combine)(A.inverse) | ||
) | ||
def consistentInverse(x: A, y: A): IsEq[A] = | ||
S.remove(x, y) <-> S.combine(x, S.inverse(y)) | ||
} | ||
|
||
def commutativeGroup(implicit A: CommutativeGroup[A]): GroupProperties = new GroupProperties( | ||
name = "commutative group", | ||
parents = List(group, commutativeMonoid) | ||
) | ||
object GroupLaws { | ||
def apply[A](implicit ev: Group[A]): GroupLaws[A] = | ||
new GroupLaws[A] { def S: Group[A] = ev } | ||
} | ||
|
||
// property classes | ||
|
||
class GroupProperties( | ||
val name: String, | ||
val parents: Seq[GroupProperties], | ||
val props: (String, Prop)* | ||
) extends RuleSet { | ||
val bases = Nil | ||
} | ||
} |
Oops, something went wrong.