/core/src/main/scala/scalaz/Ordering.scala

http://github.com/scalaz/scalaz · Scala · 82 lines · 65 code · 11 blank · 6 comment · 22 complexity · cb57f68d04138cdf17f067d2498d22f1 MD5 · raw file

  1. package scalaz
  2. /** A ternary marker of how two values relate in an ordering.
  3. *
  4. * @note scalaz calls its version of [[scala.math.Ordering]],
  5. * [[scalaz.Order]]. This `Ordering` is analogous to the
  6. * `Int`s returned by [[scala.math.Ordering]].
  7. */
  8. sealed abstract class Ordering(val toInt: Int, val name: String) extends Product with Serializable {
  9. def complement: Ordering
  10. }
  11. object Ordering extends OrderingInstances {
  12. case object LT extends Ordering(-1, "LT") { def complement = GT }
  13. case object EQ extends Ordering(0, "EQ") { def complement = EQ }
  14. case object GT extends Ordering(1, "GT") { def complement = LT }
  15. def fromLessThan[A](a1: A, a2: A)(f: (A, A) => Boolean): Ordering =
  16. if (f(a1, a2)) LT
  17. else if (f(a2, a1)) GT
  18. else EQ
  19. def fromInt(intOrdering: Int): Ordering = if (intOrdering < 0) LT else if (intOrdering > 0) GT else EQ
  20. }
  21. sealed abstract class OrderingInstances {
  22. import Ordering._
  23. implicit val orderingInstance: Enum[Ordering] with Show[Ordering] with Monoid[Ordering] = new Enum[Ordering] with Show[Ordering] with Monoid[Ordering] {
  24. def order(a1: Ordering, a2: Ordering): Ordering = (a1, a2) match {
  25. case (LT, LT) => EQ
  26. case (LT, EQ | GT) => LT
  27. case (EQ, LT) => GT
  28. case (EQ, EQ) => EQ
  29. case (EQ, GT) => LT
  30. case (GT, LT | EQ) => GT
  31. case (GT, GT) => EQ
  32. }
  33. override def show(f: Ordering): Cord = Cord(shows(f))
  34. override def shows(f: Ordering) = f.name
  35. def append(f1: Ordering, f2: => Ordering): Ordering = f1 match {
  36. case Ordering.EQ => f2
  37. case o => o
  38. }
  39. def zero: Ordering = Ordering.EQ
  40. def succ(b: Ordering) = b match {
  41. case Ordering.LT => Ordering.EQ
  42. case Ordering.EQ => Ordering.GT
  43. case Ordering.GT => Ordering.LT
  44. }
  45. def pred(b: Ordering) = b match {
  46. case Ordering.GT => Ordering.EQ
  47. case Ordering.EQ => Ordering.LT
  48. case Ordering.LT => Ordering.GT
  49. }
  50. override def succn(a: Int, b: Ordering) =
  51. if(a < 0)
  52. predn(-a, b)
  53. else if(a % 3 == 0)
  54. b
  55. else if(a % 3 == 1)
  56. succ(b)
  57. else
  58. succ(succ(b))
  59. override def predn(a: Int, b: Ordering) =
  60. if(a < 0)
  61. succn(-a, b)
  62. else if(a % 3 == 0)
  63. b
  64. else if(a % 3 == 1)
  65. pred(b)
  66. else
  67. pred(pred(b))
  68. override def min = Some(LT)
  69. override def max = Some(GT)
  70. }
  71. }