typelevel / algebra
1
package algebra.laws
2

3
import cats.kernel._
4

5
import org.typelevel.discipline.Laws
6

7
import org.scalacheck.{Arbitrary, Cogen, Prop}
8
import org.scalacheck.Prop._
9

10
import cats.kernel.instances.all._
11

12
object OrderLaws {
13
  def apply[A: Eq: Arbitrary: Cogen]: OrderLaws[A] =
14 3
    new OrderLaws[A] {
15 3
      def Equ = Eq[A]
16 3
      def Arb = implicitly[Arbitrary[A]]
17 3
      def Cog = implicitly[Cogen[A]]
18
    }
19
}
20

21
trait OrderLaws[A] extends Laws {
22

23
  implicit def Equ: Eq[A]
24
  implicit def Arb: Arbitrary[A]
25
  implicit def Cog: Cogen[A]
26

27 3
  def eqv: OrderProperties = new OrderProperties(
28 3
    name = "eq",
29 3
    parent = None,
30 3
    Rules.serializable(Equ),
31 3
    "reflexitivity-eq" -> forAll { (x: A) =>
32 3
      x ?== x
33
    },
34 3
    "symmetry-eq" -> forAll { (x: A, y: A) =>
35 3
      Equ.eqv(x, y) ?== Equ.eqv(y, x)
36
    },
37 3
    "antisymmetry-eq" -> forAll { (x: A, y: A, f: A => A) =>
38 3
      !Equ.eqv(x, y) ?|| Equ.eqv(f(x), f(y))
39
    },
40 3
    "transitivity-eq" -> forAll { (x: A, y: A, z: A) =>
41 3
      !(Equ.eqv(x, y) && Equ.eqv(y, z)) ?|| Equ.eqv(x, z)
42
    }
43
  )
44

45 3
  def partialOrder(implicit A: PartialOrder[A]): OrderProperties = new OrderProperties(
46 3
    name = "partialOrder",
47 3
    parent = Some(eqv),
48 3
    Rules.serializable(A),
49 3
    "reflexitivity" -> forAll { (x: A) =>
50 3
      x ?<= x
51
    },
52 3
    "antisymmetry" -> forAll { (x: A, y: A) =>
53 3
      !(A.lteqv(x, y) && A.lteqv(y, x)) ?|| A.eqv(x, y)
54
    },
55 3
    "transitivity" -> forAll { (x: A, y: A, z: A) =>
56 3
      !(A.lteqv(x, y) && A.lteqv(y, z)) ?|| A.lteqv(x, z)
57
    },
58 3
    "gteqv" -> forAll { (x: A, y: A) =>
59 3
      A.lteqv(x, y) ?== A.gteqv(y, x)
60
    },
61 3
    "lt" -> forAll { (x: A, y: A) =>
62 3
      A.lt(x, y) ?== (A.lteqv(x, y) && A.neqv(x, y))
63
    },
64 3
    "gt" -> forAll { (x: A, y: A) =>
65 3
      A.lt(x, y) ?== A.gt(y, x)
66
    },
67 3
    "partialCompare" -> forAll { (x: A, y: A) =>
68 3
      val c = A.partialCompare(x, y)
69 3
      ((c < 0) ?== A.lt(x, y)) && ((c == 0) ?== A.eqv(x, y)) && ((c > 0) ?== A.gt(x, y))
70
    },
71 3
    "pmin" -> forAll { (x: A, y: A) =>
72 3
      val c = A.partialCompare(x, y)
73 3
      val m = A.pmin(x, y)
74 3
      if (c < 0) m ?== Some(x)
75 3
      else if (c == 0) (m ?== Some(x)) && (m ?== Some(y))
76 3
      else if (c > 0) m ?== Some(y)
77 3
      else m ?== None
78
    },
79 3
    "pmax" -> forAll { (x: A, y: A) =>
80 3
      val c = A.partialCompare(x, y)
81 3
      val m = A.pmax(x, y)
82 3
      if (c < 0) m ?== Some(y)
83 3
      else if (c == 0) (m ?== Some(x)) && (m ?== Some(y))
84 3
      else if (c > 0) m ?== Some(x)
85 3
      else m ?== None
86
    }
87
  )
88

89 3
  def order(implicit A: Order[A]): OrderProperties = new OrderProperties(
90 3
    name = "order",
91 3
    parent = Some(partialOrder),
92 3
    "totality" -> forAll { (x: A, y: A) =>
93 3
      A.lteqv(x, y) ?|| A.lteqv(y, x)
94
    },
95 3
    "compare" -> forAll { (x: A, y: A) =>
96 3
      val c = A.compare(x, y)
97 3
      ((c < 0) ?== A.lt(x, y)) && ((c == 0) ?== A.eqv(x, y)) && ((c > 0) ?== A.gt(x, y))
98
    },
99 3
    "min" -> forAll { (x: A, y: A) =>
100 3
      val c = A.compare(x, y)
101 3
      val m = A.min(x, y)
102 3
      if (c < 0) m ?== x
103 3
      else if (c == 0) (m ?== x) && (m ?== y)
104 3
      else m ?== y
105
    },
106 3
    "max" -> forAll { (x: A, y: A) =>
107 3
      val c = A.compare(x, y)
108 3
      val m = A.max(x, y)
109 3
      if (c < 0) m ?== y
110 3
      else if (c == 0) (m ?== x) && (m ?== y)
111 3
      else m ?== x
112
    }
113
  )
114

115
  class OrderProperties(
116
    name: String,
117
    parent: Option[RuleSet],
118
    props: (String, Prop)*
119
  ) extends DefaultRuleSet(name, parent, props: _*)
120

121
}

Read our documentation on viewing source code .

Loading